Exemple #1
0
        protected override void OnCreate()
        {
            var settings     = pathSystem.Settings;
            var pointerArray = new PathMeshQueryPointer[JobsUtility.MaxJobThreadCount];

            for (var i = 0; i < JobsUtility.MaxJobThreadCount; ++i)
            {
                pointerArray[i] = new PathMeshQueryPointer
                {
                    Value = UnsafeUtility.Malloc(
                        UnsafeUtility.SizeOf <NavMeshQuery>(),
                        UnsafeUtility.AlignOf <NavMeshQuery>(),
                        Allocator.Persistent
                        )
                };

                var query = new NavMeshQuery(
                    NavMeshWorld.GetDefaultWorld(),
                    Allocator.Persistent,
                    settings.PathMeshQueryNodeMax
                    );

                queryList.Add(query);

                UnsafeUtility.CopyStructureToPtr(ref query, pointerArray[i].Value);
            }

            PointerArray = new NativeArray <PathMeshQueryPointer>(pointerArray, Allocator.Persistent);
        }
Exemple #2
0
        /// <summary>
        /// Move along the NavMeshQuery and update the position
        /// </summary>
        /// <param name="npos">Current position</param>
        /// <param name="navquery">The NavMeshQuery</param>
        /// <returns>True if position changed, false if not</returns>
        public bool MovePosition(Vector3 npos, NavMeshQuery navquery)
        {
            const int MaxVisited = 16;

            Vector3          result     = new Vector3();
            List <NavPolyId> visited    = new List <NavPolyId>(MaxVisited);
            NavPoint         startPoint = new NavPoint(path[0], pos);


            //move along navmesh and update new position
            bool status = navquery.MoveAlongSurface(ref startPoint, ref npos, out result, visited);

            if (status == true)
            {
                MergeCorridorStartMoved(path, visited);

                //adjust the position to stay on top of the navmesh
                float h = pos.Y;
                navquery.GetPolyHeight(path[0], result, ref h);
                result.Y = h;
                pos      = result;
                return(true);
            }

            return(false);
        }
Exemple #3
0
        public void FindCorners(StraightPath corners, NavMeshQuery navquery)
        {
            const float MinTargetDist = 0.01f;

            navquery.FindStraightPath(pos, target, path, corners, 0);

            //prune points in the beginning of the path which are too close
            while (corners.Count > 0)
            {
                if (((corners[0].Flags & StraightPathFlags.OffMeshConnection) != 0) ||
                    Vector3Extensions.Distance2D(corners[0].Point.Position, pos) > MinTargetDist)
                    break;

                corners.RemoveAt(0);
            }

            //prune points after an off-mesh connection
            for (int i = 0; i < corners.Count; i++)
            {
                if ((corners[i].Flags & StraightPathFlags.OffMeshConnection) != 0)
                {
                    corners.RemoveRange(i + 1, corners.Count - i);
                    break;
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// Use a local area path search to try to reoptimize this corridor
        /// </summary>
        /// <param name="navquery">The NavMeshQuery</param>
        /// <returns>True if optimized, false if not</returns>
        public bool OptimizePathTopology(NavMeshQuery navquery, NavQueryFilter filter)
        {
            if (path.Count < 3)
            {
                return(false);
            }

            const int MaxIter = 32;
            const int MaxRes  = 32;

            Path     res        = new Path();
            int      numRes     = 0;
            int      tempInt    = 0;
            NavPoint startPoint = new NavPoint(path[0], pos);
            NavPoint endPoint   = new NavPoint(path[path.Count - 1], target);

            navquery.InitSlicedFindPath(ref startPoint, ref endPoint, filter, FindPathOptions.None);
            navquery.UpdateSlicedFindPath(MaxIter, ref tempInt);
            bool status = navquery.FinalizedSlicedPathPartial(path, res);

            if (status == true && numRes > 0)
            {
                MergeCorridorStartShortcut(path, res);
                return(true);
            }

            return(false);
        }
Exemple #5
0
        public void FindCorners(StraightPath corners, NavMeshQuery navquery)
        {
            const float MinTargetDist = 0.01f;

            navquery.FindStraightPath(pos, target, path, corners, 0);

            //prune points in the beginning of the path which are too close
            while (corners.Count > 0)
            {
                if (((corners[0].Flags & StraightPathFlags.OffMeshConnection) != 0) ||
                    Vector3Extensions.Distance2D(corners[0].Point.Position, pos) > MinTargetDist)
                {
                    break;
                }

                corners.RemoveAt(0);
            }

            //prune points after an off-mesh connection
            for (int i = 0; i < corners.Count; i++)
            {
                if ((corners[i].Flags & StraightPathFlags.OffMeshConnection) != 0)
                {
                    corners.RemoveRange(i + 1, corners.Count - i);
                    break;
                }
            }
        }
Exemple #6
0
        public static NavMeshQuery CreateMeshQuery(NavMeshCreateParams meshCreateParams)
        {
            Detour.Detour.dtRawTileData navData;
            if (!Detour.Detour.dtCreateNavMeshData(meshCreateParams, out navData))
            {
                return(null);
            }

            var      m_navMesh = new NavMesh();
            dtStatus status;

            status = m_navMesh.init(navData, (int)Detour.Detour.dtTileFlags.DT_TILE_FREE_DATA);
            if (Detour.Detour.dtStatusFailed(status))
            {
                return(null);
            }

            var m_navQuery = new NavMeshQuery();

            status = m_navQuery.init(m_navMesh, 2048);
            if (Detour.Detour.dtStatusFailed(status))
            {
                return(null);
            }

            return(m_navQuery);
        }
Exemple #7
0
    // Retrace portals between corners and register if type of polygon changes:
    public static int RetracePortals(NavMeshQuery query, int startIndex, int endIndex, NativeSlice <PolygonId> path, int n, float3 termPos, ref NativeArray <NavMeshLocation> straightPath, ref NativeArray <StraightPathFlags> straightPathFlags, int maxStraightPath)
    {
        for (var i = startIndex; i < endIndex - 1; ++i)
        {
            var type1 = query.GetPolygonType(path[i]);
            var type2 = query.GetPolygonType(path[i + 1]);

            if (type1 == type2)
            {
                continue;
            }

            var status = query.GetPortalPoints(path[i], path[i + 1], out var l, out var r);

            GeometryUtils.SegmentSegmentCPA(out var cpa1, out var cpa2, l, r, straightPath[n - 1].position, termPos);
            straightPath[n] = query.CreateLocation(cpa1, path[i + 1]);

            straightPathFlags[n] = (type2 == NavMeshPolyTypes.OffMeshConnection) ? StraightPathFlags.OffMeshConnection : 0;

            if (++n == maxStraightPath)
            {
                return(maxStraightPath);
            }
        }

        straightPath[n]      = query.CreateLocation(termPos, path[endIndex]);
        straightPathFlags[n] = query.GetPolygonType(path[endIndex]) == NavMeshPolyTypes.OffMeshConnection ? StraightPathFlags.OffMeshConnection : 0;

        return(++n);
    }
Exemple #8
0
    public PathQueryQueueEcs(int nodePoolSize, int maxRequestCount)
    {
        var world = NavMeshWorld.GetDefaultWorld();

        m_Query        = new NavMeshQuery(world, Allocator.Persistent, nodePoolSize);
        m_Requests     = new NativeArray <RequestEcs>(maxRequestCount, Allocator.Persistent);
        m_ResultNodes  = new NativeArray <PolygonId>(2 * nodePoolSize, Allocator.Persistent);
        m_ResultRanges = new NativeArray <PathInfo>(maxRequestCount + 1, Allocator.Persistent);
        m_AgentIndices = new NativeArray <int>(maxRequestCount + 1, Allocator.Persistent);
        m_Costs        = new NativeArray <float>(32, Allocator.Persistent);
        for (var i = 0; i < m_Costs.Length; ++i)
        {
            m_Costs[i] = 1.0f;
        }

        m_State    = new NativeArray <QueryQueueState>(1, Allocator.Persistent);
        m_State[0] = new QueryQueueState()
        {
            requestCount       = 0,
            requestIndex       = 0,
            resultNodesCount   = 0,
            resultPathsCount   = 0,
            currentAgentIndex  = -1,
            currentPathRequest = new PathInfo()
        };
    }
Exemple #9
0
		static bool GetSteerTarget( NavMeshQuery navMeshQuery, SharpNav.Geometry.Vector3 startPos, SharpNav.Geometry.Vector3 endPos, float minTargetDist, SharpNav.Pathfinding.Path path, ref SharpNav.Geometry.Vector3 steerPos, ref StraightPathFlags steerPosFlag, ref NavPolyId steerPosRef )
		{
			StraightPath steerPath = new StraightPath();
			navMeshQuery.FindStraightPath( startPos, endPos, path, steerPath, 0 );
			int nsteerPath = steerPath.Count;
			if( nsteerPath == 0 )
				return false;

			//find vertex far enough to steer to
			int ns = 0;
			while( ns < nsteerPath )
			{
				if( ( steerPath[ ns ].Flags & StraightPathFlags.OffMeshConnection ) != 0 ||
					!InRange( steerPath[ ns ].Point.Position, startPos, minTargetDist, 1000.0f ) )
					break;

				ns++;
			}

			//failed to find good point to steer to
			if( ns >= nsteerPath )
				return false;

			steerPos = steerPath[ ns ].Point.Position;
			steerPos.Y = startPos.Y;
			steerPosFlag = steerPath[ ns ].Flags;
			if( steerPosFlag == StraightPathFlags.None && ns == ( nsteerPath - 1 ) )
				steerPosFlag = StraightPathFlags.End; // otherwise seeks path infinitely!!!
			steerPosRef = steerPath[ ns ].Point.Polygon;

			return true;
		}
Exemple #10
0
    protected override void OnCreateManager(int capacity)
    {
        var world = NavMeshWorld.GetDefaultWorld();

        query     = new NavMeshQuery(world, Allocator.Persistent);
        agentType = NavMesh.GetSettingsByIndex(1).agentTypeID;
    }
Exemple #11
0
 private void LoadNavMeshFromFile(string path)
 {
     tiledNavMesh = new NavMeshJsonSerializer().Deserialize(path);
     navMeshQuery = new NavMeshQuery(tiledNavMesh, 2048);
     hasGenerated = true;
     displayMode  = DisplayMode.NavMesh;
 }
Exemple #12
0
        public bool TrimInvalidPath(long safeRef, float[] safePos, NavMeshQuery navQuery, QueryFilter filter)
        {
            int n = 0;

            while (n < _npath && navQuery.IsValidPolyRef(_path[n], filter))
            {
                n++;
            }

            if (n == _npath)
            {
                return(true);
            }
            else if (n == 0)
            {
                Helper.VCopy(ref _pos, safePos);
                _path[0] = safeRef;
                _npath   = 1;
            }
            else
            {
                _npath = n;
            }

            float[] tgt = new float[3];
            Helper.VCopy(ref tgt, _target);
            navQuery.ClosestPointOnPolyBoundary(_path[_npath - 1], tgt, ref _target);

            return(true);
        }
Exemple #13
0
        /// <summary>
        /// Use a local area path search to try to reoptimize this corridor
        /// </summary>
        /// <param name="navquery">The NavMeshQuery</param>
        /// <returns>True if optimized, false if not</returns>
        public bool OptimizePathTopology(NavMeshQuery navquery)
        {
            if (pathCount < 3)
            {
                return(false);
            }

            const int MaxIter = 32;
            const int MaxRes  = 32;

            PolyId[] res     = new PolyId[MaxRes];
            int      numRes  = 0;
            int      tempInt = 0;

            navquery.InitSlicedFindPath(new NavPoint(path[0], pos), new NavPoint(path[pathCount - 1], target));
            navquery.UpdateSlicedFindPath(MaxIter, ref tempInt);
            bool status = navquery.FinalizedSlicedPathPartial(path, pathCount, res, ref numRes, MaxRes);

            if (status == true && numRes > 0)
            {
                pathCount = MergeCorridorStartShortcut(path, pathCount, maxPath, res, numRes);
                return(true);
            }

            return(false);
        }
        protected override void OnCreate()
        {
            var pointerArray = new NavMeshQueryPointer[JobsUtility.MaxJobThreadCount];

            for (int i = 0; i < JobsUtility.MaxJobThreadCount; ++i)
            {
                pointerArray[i] = new NavMeshQueryPointer
                {
                    Value = UnsafeUtility.Malloc(
                        UnsafeUtility.SizeOf <NavMeshQuery>(),
                        UnsafeUtility.AlignOf <NavMeshQuery>(),
                        Allocator.Persistent
                        )
                };

                var query = new NavMeshQuery(
                    NavMeshWorld.GetDefaultWorld(),
                    Allocator.Persistent,
                    NavConstants.PATH_NODE_MAX
                    );

                queryList.Add(query);

                UnsafeUtility.CopyStructureToPtr(ref query, pointerArray[i].Value);
            }

            PointerArray = new NativeArray <NavMeshQueryPointer>(pointerArray, Allocator.Persistent);
        }
Exemple #15
0
        public bool LoadNavMesh(string mapName)
        {
            bool   retCode = false;
            string path    = ConfigFileDir + mapName + ".bytes";

            NavMeshInfo navInfo = MapMgr.Inst().GetNavMeshInfo(mapName);

            if (navInfo == null)
            {
                retCode = LoadNavMeshByJsonFile(path, ref m_MapNavMesh);
                if (MapNavMesh == null || retCode == false)
                {
                    Console.WriteLine("LoadNavMeshByJsonFile {0} failed", path);
                    return(false);
                }

                m_MapNavMeshQuery = new NavMeshQuery();

                m_MapNavMeshQuery.Init(MapNavMesh, (int)MapDefine.MAX_NAV_POLYS);

                NavMeshInfo newNavInfo = new NavMeshInfo();
                newNavInfo.pdtNavMesh      = MapNavMesh;
                newNavInfo.pdtNavMeshQuery = MapNavMeshQuery;

                MapMgr.Inst().AddNavMeshInfo(mapName, newNavInfo);
            }
            else
            {
                m_MapNavMesh      = navInfo.pdtNavMesh;
                m_MapNavMeshQuery = navInfo.pdtNavMeshQuery;
            }

            return(true);
        }
Exemple #16
0
    public void TryFindPath(Vector3 start, Vector3 end)
    {
        using (var polygonIds = new NativeArray <PolygonId>(100, Allocator.Persistent))
            using (var query = new NavMeshQuery(NavMeshWorld.GetDefaultWorld(), Allocator.Persistent, 100))
            {
                int maxIterations = 1024;
                var from          = query.MapLocation(start, Vector3.one * 10, 0);
                var to            = query.MapLocation(end, Vector3.one * 10, 0);

                var status = query.BeginFindPath(from, to);

                status = query.UpdateFindPath(maxIterations, out int currentIterations);

                var finalStatus = query.EndFindPath(out int pathLength);
                var pathResult  = query.GetPathResult(polygonIds);

                var straightPath = new NativeArray <NavMeshLocation>(pathLength, Allocator.Temp);
                paths = new Vector3[pathResult];

                for (int i = 0; i < pathResult; i++)
                {
                    var polyId           = polygonIds[i];
                    var polyWorldToLocal = query.PolygonWorldToLocalMatrix(polyId);

                    var b = query.CreateLocation(paths[i], polyId);
                    paths[i] = b.position;
                    //Debug.Log(b.position);
                }

                //Debug.Log(pathResult);
                Debug.DrawLine(from.position, to.position);
            }
    }
        public virtual void trimInvalidPath(long safeRef, float[] safePos, NavMeshQuery navquery, QueryFilter filter)
        {
            // Keep valid path as far as possible.
            int n = 0;

            while (n < m_path.Count && navquery.isValidPolyRef(m_path[n], filter))
            {
                n++;
            }

            if (n == 0)
            {
                // The first polyref is bad, use current safe values.
                DetourCommon.vCopy(m_pos, safePos);
                m_path.Clear();
                m_path.Add(safeRef);
            }
            else if (n < m_path.Count)
            {
                m_path = m_path.GetRange(0, n);
                // The path is partially usable.
            }


            navquery.closestPointOnPolyBoundary(m_path[m_path.Count - 1], m_target, temp);
            // Clamp target pos to last poly
            DetourCommon.vCopy(m_target, temp);
        }
        IEnumerator StartQuery()
        {
            NavMeshWorld world = NavMeshWorld.GetDefaultWorld();
            NavMeshQuery query = new NavMeshQuery(world, Allocator.Persistent, maxPath);

            NavMeshLocation startLocation = query.MapLocation(start.position, Vector3.up * extents, 0);
            NavMeshLocation endLocation   = query.MapLocation(end.position, Vector3.up * extents, 0);
            PathQueryStatus status        = query.BeginFindPath(startLocation, endLocation);

            yield return(new WaitWhile(() => {
                status = query.UpdateFindPath(8, out int iterationsPerformed);
                return status == PathQueryStatus.InProgress;
            }));

            status = query.EndFindPath(out int pathsize);

            NativeArray <PolygonId> path = new NativeArray <PolygonId>(pathsize, Allocator.Temp);
            int pathResult = query.GetPathResult(path);

            //NativeArray<NavMeshLocation> pathStraight = new NativeArray<NavMeshLocation>(maxPath, Allocator.Temp);
            ////NativeArray<StraightPathFlag> pathStreaigthFlag = new NativeArray<StraightPathFlags>(maxPath, Allocator.Temp);
            //NativeArray<float> vertexSize = new NativeArray<float>(maxPath, Allocator.Temp);
            //
            //int straghtPathCount = 0;

            for (var i = 0; i < pathResult; i++)
            {
                var p = path[i];

                var loc    = query.CreateLocation(start.position, p);
                var target = loc.position;
            }

            query.Dispose();
        }
Exemple #19
0
        // This function checks if the path has a small U-turn, that is,
        // a polygon further in the path is adjacent to the first polygon
        // in the path. If that happens, a shortcut is taken.
        // This can happen if the target (T) location is at tile boundary,
        // and we're (S) approaching it parallel to the tile edge.
        // The choice at the vertex can be arbitrary,
        //  +---+---+
        //  |:::|:::|
        //  +-S-+-T-+
        //  |:::|   | <-- the step can end up in here, resulting U-turn path.
        //  +---+---+
        static int fixupShortcuts(uint[] path, int npath, NavMeshQuery navQuery)
        {
            if (npath < 3)
            {
                return(npath);
            }

            // Get connected polygons
            const int maxNeis = 16;

            uint[] neis  = new uint[maxNeis];
            int    nneis = 0;

            Detour.dtMeshTile tile = null;
            Detour.dtPoly     poly = null;
            if (Detour.dtStatusFailed(navQuery.getAttachedNavMesh().getTileAndPolyByRef(path[0], ref tile, ref poly)))
            {
                return(npath);
            }

            for (uint k = poly.firstLink; k != Detour.DT_NULL_LINK; k = tile.links[k].next)
            {
                Detour.dtLink link = tile.links[k];
                if (link.polyRef != 0)
                {
                    if (nneis < maxNeis)
                    {
                        neis[nneis++] = link.polyRef;
                    }
                }
            }

            // If any of the neighbour polygons is within the next few polygons
            // in the path, short cut to that polygon directly.
            const int maxLookAhead = 6;
            int       cut          = 0;

            for (int i = Math.Min(maxLookAhead, npath) - 1; i > 1 && cut == 0; i--)
            {
                for (int j = 0; j < nneis; j++)
                {
                    if (path[i] == neis[j])
                    {
                        cut = i;
                        break;
                    }
                }
            }
            if (cut > 1)
            {
                int offset = cut - 1;
                npath -= offset;
                for (int i = 1; i < npath; i++)
                {
                    path[i] = path[i + offset];
                }
            }

            return(npath);
        }
Exemple #20
0
    // Use this for initialization
    void Start()
    {
        var navQuery = FindObjectOfType(typeof(RecastNavMeshQuery)) as RecastNavMeshQuery;

        if (navQuery != null)
        {
            _navMeshQuery = navQuery._navMeshQuery;
            filter        = navQuery.filter;
            crowd         = navQuery.Crowd;

            param = new CrowdAgentParams
            {
                Radius                = Radius,
                Height                = Height,
                MaxAcceleration       = MaxAcceleration,
                MaxSpeed              = MaxSpeed,
                CollisionQueryRange   = CollisionQueryRange,
                PathOptimizationRange = PathOptimizationRange,
                UpdateFlags           = UpdateFlags,
                ObstacleAvoidanceType = ObstacleAvoidanceType,
                SeparationWeight      = SeparationWeight
            };
            AgentId = navQuery.Crowd.AddAgent(new[] { transform.position.x, transform.position.y, transform.position.z }, param);
            ResetTarget();
        }
        else
        {
            Debug.LogError("Scene does not have a Nav Mesh Query, one must be added.");
        }
    }
Exemple #21
0
        public bool OptimizePathTopology(NavMeshQuery navQuery, QueryFilter filter)
        {
            if (_npath < 3)
            {
                return(false);
            }

            int MaxIters = 32;
            int MaxRes   = 32;

            long[] res  = new long[MaxRes];
            int    nres = 0;

            navQuery.InitSlicedFindPath(_path[0], _path[_npath - 1], _pos, _target, filter);
            int doneIters = 0;

            navQuery.UpdateSlicedFindPath(MaxIters, ref doneIters);

            Status status = navQuery.FinalizeSlicedFindPathPartial(_path, _npath, ref res, ref nres, MaxRes);

            if ((status & Status.Success) != 0 && nres > 0)
            {
                _npath = MergeCorridorStartShortcut(ref _path, _npath, _maxPath, res, nres);
                return(true);
            }

            return(false);
        }
Exemple #22
0
        /// <summary>
        /// Move along the NavMeshQuery and update the position
        /// </summary>
        /// <param name="npos">Current position</param>
        /// <param name="navquery">The NavMeshQuery</param>
        /// <returns>True if position changed, false if not</returns>
        public bool MovePosition(Vector3 npos, NavMeshQuery navquery)
        {
            //move along navmesh and update new position
            Vector3   result     = new Vector3();
            const int MaxVisited = 16;

            PolyId[]      visited     = new PolyId[MaxVisited];
            List <PolyId> listVisited = new List <PolyId>(MaxVisited);
            bool          status      = navquery.MoveAlongSurface(new NavPoint(path[0], pos), npos, ref result, listVisited);

            visited = listVisited.ToArray();             //HACK why?

            if (status == true)
            {
                pathCount = MergeCorridorStartMoved(path, pathCount, maxPath, visited, listVisited.Count);

                //adjust the position to stay on top of the navmesh
                float h = pos.Y;
                navquery.GetPolyHeight(path[0], result, ref h);
                result.Y = h;
                pos      = result;
                return(true);
            }

            return(false);
        }
Exemple #23
0
        public bool Init(int maxAgents, float maxAgentRadius, NavMesh nav)
        {
            Purge();
            _maxAgents      = maxAgents;
            _maxAgentRadius = maxAgentRadius;

            Helper.VSet(ref _ext, _maxAgentRadius * 2.0f, _maxAgentRadius * 1.5f, _maxAgentRadius * 2.0f);

            _grid = new ProximityGrid();
            _grid.Init(_maxAgents * 4, maxAgentRadius * 3);

            _obstacleQuery = new ObstacleAvoidanceQuery();
            _obstacleQuery.Init(6, 8);

            for (int i = 0; i < _obstacleQueryParams.Length; i++)
            {
                _obstacleQueryParams[i] = new ObstacleAvoidanceParams
                {
                    velBias       = 0.4f,
                    weightDesVel  = 2.0f,
                    weightCurVel  = 0.75f,
                    weightSide    = 0.75f,
                    weightToi     = 2.5f,
                    horizTime     = 2.5f,
                    gridSize      = 33,
                    adaptiveDivs  = 7,
                    adaptiveRings = 2,
                    adaptiveDepth = 5
                };
            }

            _maxPathResult = 256;
            _pathResult    = new long[_maxPathResult];

            _pathq = new PathQueue();
            _pathq.Init(_maxPathResult, MaxPathQueueNodes, nav);

            _agents       = new CrowdAgent[_maxAgents];
            _activeAgents = new CrowdAgent[_maxAgents];
            _agentAnims   = new CrowdAgentAnimation[_maxAgents];

            for (int i = 0; i < _maxAgents; i++)
            {
                _agents[i]        = new CrowdAgent();
                _agents[i].Active = false;
                _agents[i].Corridor.Init(_maxPathResult);
            }

            for (int i = 0; i < _maxAgents; i++)
            {
                _agentAnims[i]        = new CrowdAgentAnimation();
                _agentAnims[i].Active = false;
            }

            _navQuery = new NavMeshQuery();
            _navQuery.Init(nav, MaxCommonNodes);

            return(true);
        }
Exemple #24
0
 private void Purge()
 {
     _navQuery = null;
     for (int i = 0; i < MaxQueue; i++)
     {
         _queue[i].path = null;
     }
 }
    protected override void OnCreate()
    {
        AgentsGroup = GetEntityQuery(typeof(NavAgent), ComponentType.ReadWrite <Translation>(),
                                     ComponentType.ReadWrite <Rotation>(), ComponentType.ReadWrite <LocalToWorld>());
        var navMeshWorld = NavMeshWorld.GetDefaultWorld();

        NavMeshQuery = new NavMeshQuery(navMeshWorld, Allocator.Persistent, 100);
    }
    public void Awake()
    {
        Instance      = this;    // worst singleton ever but it works
        entityManager = World.Active.GetExistingManager <EntityManager>();
        var navMeshWorld = NavMeshWorld.GetDefaultWorld();

        mapLocationQuery = new NavMeshQuery(navMeshWorld, Allocator.Persistent);
    }
 public FindNearestPolyQuery(NavMeshQuery query, Vector3 center)
 {
     m_query              = query;
     m_center             = center;
     m_nearestDistanceSqr = float.MaxValue;
     m_nearestRef         = 0;
     m_nearestPoint       = Vector3.Zero;
 }
    private bool GetSteerTarget(NavMeshQuery navMeshQuery, float[] startPos, float[] endPos, float minTargetDistance,
                                long[] path, int pathSize, ref float[] steerPos, ref short steerPosFlag, ref long steerPosRef)
    {
        float[] outPoints      = null;
        int     outPointsCount = 0;

        return(GetSteerTarget(navMeshQuery, startPos, endPos, minTargetDistance, path, pathSize, ref steerPos, ref steerPosFlag, ref steerPosRef, ref outPoints, ref outPointsCount));
    }
Exemple #29
0
        public Pather(string continent, ConnectionHandlerDelegate connectionHandler)
        {
            ConnectionHandler = connectionHandler;

            Continent = continent.Substring(continent.LastIndexOf('\\') + 1);

            if (Directory.Exists(continent))
            {
                _meshPath = continent;
            }
            else
            {
                var assembly = Assembly.GetCallingAssembly().Location;
                var dir      = Path.GetDirectoryName(assembly);
                if (Directory.Exists(dir + "\\Meshes"))
                {
                    _meshPath = dir + "\\Meshes\\" + continent;
                }
                else
                {
                    _meshPath = dir + "\\" + continent;
                }
            }

            if (!Directory.Exists(_meshPath))
            {
                throw new NavMeshException(DetourStatus.Failure, "No mesh for " + continent + " (Path: " + _meshPath + ")");
            }

            _mesh = new NavMesh();
            DetourStatus status;

            // check if this is a dungeon and initialize our mesh accordingly
            string dungeonPath = GetDungeonPath();

            if (File.Exists(dungeonPath))
            {
                var data = File.ReadAllBytes(dungeonPath);
                status = _mesh.Initialize(data);
                AddMemoryPressure(data.Length);
                IsDungeon = true;
            }
            else
            {
                status = _mesh.Initialize(32768, 4096, Utility.Origin, Utility.TileSize, Utility.TileSize);
            }

            if (status.HasFailed())
            {
                throw new NavMeshException(status, "Failed to initialize the mesh");
            }

            _query = new NavMeshQuery(new PatherCallback(this));
            _query.Initialize(_mesh, 65536);
            Filter = new QueryFilter {
                IncludeFlags = 0xFFFF, ExcludeFlags = 0x0
            };
        }
Exemple #30
0
        static bool getSteerTarget(NavMeshQuery navQuery, float[] startPos, float[] endPos,
                                   float minTargetDist,
                                   uint[] path, int pathSize,
                                   float[] steerPos, ref byte steerPosFlag, ref uint 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];
            uint[]  steerPathPolys = new uint[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);
        }
Exemple #31
0
        static void TestNavmesh(NavMeshBuilder build)
        {
            // Azeroth 28 28 / Deathknell (wow-style coordinates)
            // Outside church: 1843.734 1604.214 94.55994
            // Inside church: 1844.074 1642.581 97.62832
            // Outside spawn: 1672.226 1662.989 139.2343
            // Inside spawn: 1665.264 1678.277 120.5302
            // Outside cave: 2051.3 1807.121 102.5225
            // Inside cave: 2082.813 1950.718 98.04765
            // Outside house: 1861.465 1582.03 92.79533
            // Upstairs house: 1859.929 1560.804 99.07755

            var tmesh = new TiledNavMesh(build);

            var query   = new NavMeshQuery(tmesh, 65536);
            var extents = new Vector3(5f, 5f, 5f);

            var posStart = WoWToSharpNav(new Vector3(1665.2f, 1678.2f, 120.5f)); // Inside spawn
            var posEnd   = WoWToSharpNav(new Vector3(1672.2f, 1662.9f, 139.2f)); // Outside spawn

            NavPoint endPt;

            query.FindNearestPoly(ref posEnd, ref extents, out endPt);

            NavPoint startPt;

            query.FindNearestPoly(ref posStart, ref extents, out startPt);

            var path = new List <int>();

            if (!query.FindPath(ref startPt, ref endPt, path))
            {
                Console.WriteLine("No path!");
            }

            Vector3 actualStart = new Vector3();

            query.ClosestPointOnPoly(startPt.Polygon, startPt.Position, ref actualStart);

            Vector3 actualEnd = new Vector3();

            query.ClosestPointOnPoly(endPt.Polygon, endPt.Position, ref actualEnd);

            var smoothPath = new List <Vector3>();

            Vector3[] straightPath = new Vector3[2048];
            int[]     pathFlags    = new int[2048];
            int[]     pathRefs     = new int[2048];
            int       pathCount    = -1;

            query.FindStraightPath(actualStart, actualEnd, path.ToArray(), path.Count, straightPath, pathFlags, pathRefs, ref pathCount, 2048, PathBuildFlags.AllCrossingVertices);

            foreach (var v in straightPath)
            {
                Console.WriteLine(v);
            }
        }
Exemple #32
0
        public PathQueue(int maxSearchNodeCount, ref TiledNavMesh nav)
        {
            this.navquery = new NavMeshQuery(nav, maxSearchNodeCount);
            this.navqueryfilter = new NavQueryFilter();

            this.queue = new PathQuery[MaxQueue];
            for (int i = 0; i < MaxQueue; i++)
            {
                queue[i].Index = 0;
                queue[i].Path = new Path();
            }

            this.queueHead = 0;
        }
Exemple #33
0
        public PathQueue(int maxPathSize, int maxSearchNodeCount, ref TiledNavMesh nav)
        {
            this.navquery = new NavMeshQuery(nav, maxSearchNodeCount);

            this.maxPathSize = maxPathSize;
            this.queue = new PathQuery[MaxQueue];
            for (int i = 0; i < MaxQueue; i++)
            {
                queue[i].Reference = Invalid;
                queue[i].Path = new int[maxPathSize];
            }

            this.queueHead = 0;
        }
Exemple #34
0
        public WowMapPather(string continent)
        {

            fullFileName = continent;
            Continent = continent.Substring(continent.LastIndexOf('\\') + 1);

            if (Directory.Exists(continent))
                _meshPath = continent;
            else
            {
                var assembly = Assembly.GetCallingAssembly().Location;
                var dir = Path.GetDirectoryName(assembly);
                if (Directory.Exists(dir + "\\Meshes"))
                    _meshPath = dir + "\\Meshes\\" + continent;
                else
                    _meshPath = dir + "\\" + continent;
            }

            if (!Directory.Exists(_meshPath))
                throw new Exception("No mesh for " + continent + " (Path: " + _meshPath + ")");

            _mesh = new NavMesh();
            DetourStatus status;

            // check if this is a dungeon and initialize our mesh accordingly
            string dungeonPath = GetDungeonPath();
            if (File.Exists(dungeonPath))
            {
                var data = File.ReadAllBytes(dungeonPath);
                status = _mesh.Initialize(data);
                IsDungeon = true;
            }
            else
                status = _mesh.Initialize(32768, 4096, Utility.Origin, Utility.TileSize, Utility.TileSize);

            if (status.HasFailed())
                throw new Exception("Failed to initialize the mesh");

            // _query = new NavMeshQuery(new PatherCallback(this));
            //TODO: Add Callback for Dynamic Tile Loading
            _query = new NavMeshQuery();
             _query.Initialize(_mesh, 65536);
            Filter = new QueryFilter { IncludeFlags = 0xFFFF, ExcludeFlags = 0x0 };
        }
Exemple #35
0
        public FloodFill(NavMesh mesh)
        {
            Mesh = mesh;

            _query = new NavMeshQuery();
            if (!_query.Initialize(Mesh, 1024).HasSucceeded())
                throw new Exception("Failed to initialize navigation mesh query");

            _filter = new QueryFilter();

            var param = Mesh.Parameter;
            // detour guarantees these are 2^x
            var tileBits = (int) Math.Log(param.MaxTiles, 2);
            var polyBits = (int) Math.Log(param.MaxPolygons, 2);
            // we also don't care about salt, so create a mask to cut these off just in case
            Visited = new bool[1 << (tileBits + polyBits)];
            VisitedMask = (1 << (tileBits + polyBits)) - 1;

            _open = new Queue<uint>(100);
        }
Exemple #36
0
        public void TestNavMesh(byte[] data)
        {

            var extents = new Vector3(2.5f, 2.5f, 2.5f).ToFloatArray();


            // var startVec = new Vector3(-9467.8f, 64.2f, 55.9f);
            //var endVec = new Vector3(-9248.9f, -93.35f, 70.3f);


            //Vector3 startVec = new Vector3(1672.2f, 1662.9f, 139.2f);
            //Vector3 startVec = new Vector3(1665.2f, 1678.2f, 120.5f);

            Vector3 startVec = new Vector3 ( -8949.95f, -132.493f, 83.5312f );
            Vector3 endVec = new Vector3 ( -9046.507f, -45.71962f, 88.33186f );

            var start = startVec.ToRecast().ToFloatArray();
            var end = endVec.ToRecast().ToFloatArray();

            NavMesh _mesh = new NavMesh();
            _mesh.Initialize(32768, 4096, Helpers.Origin, Helpers.TileSize, Helpers.TileSize);
            var meshData = data;
            MeshTile tile;
            _mesh.AddTile(data, out tile);
            NavMeshQuery _query = new NavMeshQuery();
            _query.Initialize(_mesh, 65536);
            QueryFilter Filter = new QueryFilter { IncludeFlags = 0xFFFF, ExcludeFlags = 0x0 };

            var startRef = _query.FindNearestPolygon(start, extents, Filter);
           

            var endRef = _query.FindNearestPolygon(end, extents, Filter);


            uint[] pathCorridor;
            var status = _query.FindPath(startRef, endRef, start, end, Filter, out pathCorridor);
            if (status.Equals(DetourStatus.Failure) || pathCorridor == null)
                throw new Exception("FindPath failed, start: " + startRef + " end: " + endRef);

            if (status.HasFlag(DetourStatus.PartialResult))
                Console.WriteLine("Warning, partial result: " + status);

            float[] finalPath;
            StraightPathFlag[] pathFlags;
            uint[] pathRefs;
            status = _query.FindStraightPath(start, end, pathCorridor, out finalPath, out pathFlags, out pathRefs);
            if (status.Equals(DetourStatus.Failure) || (finalPath == null || pathFlags == null || pathRefs == null))
                throw new Exception("FindStraightPath failed, refs in corridor: " + pathCorridor.Length);

            

        }
Exemple #37
0
        /// <summary>
        /// Move along the NavMeshQuery and update the position
        /// </summary>
        /// <param name="npos">Current position</param>
        /// <param name="navquery">The NavMeshQuery</param>
        /// <returns>True if position changed, false if not</returns>
        public bool MovePosition(Vector3 npos, NavMeshQuery navquery)
        {
            const int MaxVisited = 16;

            Vector3 result = new Vector3();
            List<NavPolyId> visited = new List<NavPolyId>(MaxVisited);
            NavPoint startPoint = new NavPoint(path[0], pos);

            //move along navmesh and update new position
            bool status = navquery.MoveAlongSurface(ref startPoint, ref npos, out result, visited);

            if (status == true)
            {
                MergeCorridorStartMoved(path, visited);

                //adjust the position to stay on top of the navmesh
                float h = pos.Y;
                navquery.GetPolyHeight(path[0], result, ref h);
                result.Y = h;
                pos = result;
                return true;
            }

            return false;
        }
Exemple #38
0
        /// <summary>
        /// Use a local area path search to try to reoptimize this corridor
        /// </summary>
        /// <param name="navquery">The NavMeshQuery</param>
        /// <returns>True if optimized, false if not</returns>
        public bool OptimizePathTopology(NavMeshQuery navquery, NavQueryFilter filter)
        {
            if (path.Count < 3)
                return false;

            const int MaxIter = 32;
            const int MaxRes = 32;

            Path res = new Path();
            int numRes = 0;
            int tempInt = 0;
            NavPoint startPoint = new NavPoint(path[0], pos);
            NavPoint endPoint = new NavPoint(path[path.Count - 1], target);
            navquery.InitSlicedFindPath(ref startPoint, ref endPoint, filter, FindPathOptions.None);
            navquery.UpdateSlicedFindPath(MaxIter, ref tempInt);
            bool status = navquery.FinalizedSlicedPathPartial(path, res);

            if (status == true && numRes > 0)
            {
                MergeCorridorStartShortcut(path, res);
                return true;
            }

            return false;
        }
Exemple #39
0
        /// <summary>
        /// Use an efficient local visibility search to try to optimize the corridor between the current position and the next.
        /// </summary>
        /// <param name="next">The next postion</param>
        /// <param name="pathOptimizationRange">The range</param>
        /// <param name="navquery">The NavMeshQuery</param>
        public void OptimizePathVisibility(Vector3 next, float pathOptimizationRange, NavMeshQuery navquery)
        {
            //clamp the ray to max distance
            Vector3 goal = next;
            float dist = Vector3Extensions.Distance2D(pos, goal);

            //if too close to the goal, do not try to optimize
            if (dist < 0.01f)
                return;

            dist = Math.Min(dist + 0.01f, pathOptimizationRange);

            //adjust ray length
            Vector3 delta = goal - pos;
            goal = pos + delta * (pathOptimizationRange / dist);

            NavPoint startPoint = new NavPoint(path[0], pos);
            Path raycastPath = new Path();
            RaycastHit hit;

            navquery.Raycast(ref startPoint, ref goal, RaycastOptions.None, out hit, raycastPath);
            if (raycastPath.Count > 1 && hit.T > 0.99f)
            {
                MergeCorridorStartShortcut(raycastPath, raycastPath);
            }
        }
Exemple #40
0
		/// <summary>
		/// Use an efficient local visibility search to try to optimize the corridor between the current position and the next.
		/// </summary>
		/// <param name="next">The next postion</param>
		/// <param name="pathOptimizationRange">The range</param>
		/// <param name="navquery">The NavMeshQuery</param>
		public void OptimizePathVisibility(Vector3 next, float pathOptimizationRange, NavMeshQuery navquery)
		{
			//clamp the ray to max distance
			Vector3 goal = next;
			float dist = Vector3Extensions.Distance2D(pos, goal);

			//if too close to the goal, do not try to optimize
			if (dist < 0.01f)
				return;

			dist = Math.Min(dist + 0.01f, pathOptimizationRange);

			//adjust ray length
			Vector3 delta = goal - pos;
			goal = pos + delta * (pathOptimizationRange / dist);

			const int MaxRes = 32;
			PolyId[] res = new PolyId[MaxRes];
			float t = 0;
			Vector3 norm = new Vector3();
			int nres = 0;
			navquery.Raycast(new NavPoint(path[0], pos), goal, ref t, ref norm, res, ref nres, MaxRes);
			if (nres > 1 && t > 0.99f)
			{
				pathCount = MergeCorridorStartShortcut(path, pathCount, maxPath, res, nres);
			}
		}
Exemple #41
0
    // Use this for initialization
    void Start()
    {
        var navQuery = FindObjectOfType(typeof(RecastNavMeshQuery)) as RecastNavMeshQuery;
        if (navQuery != null)
        {
            _navMeshQuery = navQuery._navMeshQuery;
            filter = navQuery.filter;
            crowd = navQuery.Crowd;

            param = new CrowdAgentParams
            {
                Radius = Radius,
                Height = Height,
                MaxAcceleration = MaxAcceleration,
                MaxSpeed = MaxSpeed,
                CollisionQueryRange = CollisionQueryRange,
                PathOptimizationRange = PathOptimizationRange,
                UpdateFlags = UpdateFlags,
                ObstacleAvoidanceType = ObstacleAvoidanceType,
                SeparationWeight = SeparationWeight
            };
            AgentId = navQuery.Crowd.AddAgent(new[] { transform.position.x, transform.position.y, transform.position.z }, param);
            ResetTarget();
        }
        else
        {
            Debug.LogError("Scene does not have a Nav Mesh Query, one must be added.");
        }
    }
Exemple #42
0
		public bool MoveOverOffmeshConnection(PolyId offMeshConRef, PolyId[] refs, ref Vector3 startPos, ref Vector3 endPos, NavMeshQuery navquery)
		{
			//advance the path up to and over the off-mesh connection
			PolyId prevRef = PolyId.Null, polyRef = path[0];
			int npos = 0;
			while (npos < pathCount && polyRef != offMeshConRef)
			{
				prevRef = polyRef;
				polyRef = path[npos];
				npos++;
			}

			if (npos == pathCount)
			{
				//could not find offMeshConRef
				return false;
			}

			//prune path
			for (int i = npos; i < pathCount; i++)
				path[i - npos] = path[i];
			pathCount -= npos;

			refs[0] = prevRef;
			refs[1] = polyRef;

			TiledNavMesh nav = navquery.NavMesh;

			if (nav.GetOffMeshConnectionPolyEndPoints(refs[0], refs[1], ref startPos, ref endPos) == true)
			{
				pos = endPos;
				return true;
			}

			return false;
		}
 /// <summary>
 /// Tries to find the straightest path between 2 polygons
 /// </summary>
 /// <param name="navMeshQuery"></param>
 /// <param name="startPos"></param>
 /// <param name="endPos"></param>
 /// <param name="minTargetDistance"></param>
 /// <param name="path"></param>
 /// <param name="pathSize"></param>
 /// <param name="steerPos"></param>
 /// <param name="steerPosFlag"></param>
 /// <param name="steerPosRef"></param>
 /// <param name="outPoints"></param>
 /// <param name="outPointCount"></param>
 /// <returns></returns>
 private bool GetSteerTarget(NavMeshQuery navMeshQuery, float[] startPos, float[] endPos, float minTargetDistance,
                             long[] path, int pathSize, ref float[] steerPos, ref short steerPosFlag,
                             ref long steerPosRef)
 {
     float[] outPoints = null;
     int outPointsCount = 0;
     return GetSteerTarget(navMeshQuery, startPos, endPos, minTargetDistance,
                           path, pathSize, ref steerPos, ref steerPosFlag,
                           ref steerPosRef, ref outPoints, ref outPointsCount);
 }
Exemple #44
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Crowd" /> class.
        /// </summary>
        /// <param name="maxAgents">The maximum agents allowed</param>
        /// <param name="maxAgentRadius">The maximum radius for an agent</param>
        /// <param name="navMesh">The navigation mesh</param>
        public Crowd(int maxAgents, float maxAgentRadius, ref TiledNavMesh navMesh)
        {
            this.maxAgents = maxAgents;
            this.maxAgentRadius = maxAgentRadius;

            this.ext = new Vector3(maxAgentRadius * 2.0f, maxAgentRadius * 1.5f, maxAgentRadius * 2.0f);

            //initialize proximity grid
            this.grid = new ProximityGrid<Agent>(maxAgents * 4, maxAgentRadius * 3);

            //allocate obstacle avoidance query
            this.obstacleQuery = new ObstacleAvoidanceQuery(6, 8);

            //initialize obstancle query params
            this.obstacleQueryParams = new ObstacleAvoidanceQuery.ObstacleAvoidanceParams[AgentMaxObstacleAvoidanceParams];
            for (int i = 0; i < this.obstacleQueryParams.Length; i++)
            {
                this.obstacleQueryParams[i].VelBias = 0.4f;
                this.obstacleQueryParams[i].WeightDesVel = 2.0f;
                this.obstacleQueryParams[i].WeightCurVel = 0.75f;
                this.obstacleQueryParams[i].WeightSide = 0.75f;
                this.obstacleQueryParams[i].WeightToi = 2.5f;
                this.obstacleQueryParams[i].HorizTime = 2.5f;
                this.obstacleQueryParams[i].GridSize = 33;
                this.obstacleQueryParams[i].AdaptiveDivs = 7;
                this.obstacleQueryParams[i].AdaptiveRings = 2;
                this.obstacleQueryParams[i].AdaptiveDepth = 5;
            }

            this.pathq = new PathQueue(4096, ref navMesh);

            this.agents = new Agent[maxAgents];
            this.activeAgents = new Agent[maxAgents];
            this.agentAnims = new AgentAnimation[maxAgents];

            for (int i = 0; i < maxAgents; i++)
            {
                this.agents[i] = new Agent();
            }

            for (int i = 0; i < maxAgents; i++)
            {
                this.agentAnims[i].Active = false;
            }

            //allocate nav mesh query
            this.navQuery = new NavMeshQuery(navMesh, 512);
        }
    /// <summary>
    /// Builds the initial query, normally called by awake
    /// Can be callen manually with a different nav mesh.
    /// </summary>
    /// <param name="navMesh"></param>
    public void InitializeQuery(Detour.NavMesh navMesh)
    {
        _navMeshQuery = new NavMeshQuery();
        _navMeshQuery.Init(navMesh, 2048);
        filter = new QueryFilter();

        // These values need to me modifiable in the editor later using RecastArea
        filter.IncludeFlags = 15;
        filter.ExcludeFlags = 0;
        filter.SetAreaCost(1, 1.0f);
        filter.SetAreaCost(2, 10.0f);
        filter.SetAreaCost(3, 1.0f);
        filter.SetAreaCost(4, 1.0f);
        filter.SetAreaCost(5, 2);
        filter.SetAreaCost(6, 1.5f);
    }
Exemple #46
0
		/// <summary>
		/// Move along the NavMeshQuery and update the position
		/// </summary>
		/// <param name="npos">Current position</param>
		/// <param name="navquery">The NavMeshQuery</param>
		/// <returns>True if position changed, false if not</returns>
		public bool MovePosition(Vector3 npos, NavMeshQuery navquery)
		{
			//move along navmesh and update new position
			Vector3 result = new Vector3();
			const int MaxVisited = 16;
			PolyId[] visited = new PolyId[MaxVisited];
			List<PolyId> listVisited = new List<PolyId>(MaxVisited);
			bool status = navquery.MoveAlongSurface(new NavPoint(path[0], pos), npos, ref result, listVisited);
			visited = listVisited.ToArray(); //HACK why?

			if (status == true)
			{
				pathCount = MergeCorridorStartMoved(path, pathCount, maxPath, visited, listVisited.Count);

				//adjust the position to stay on top of the navmesh
				float h = pos.Y;
				navquery.GetPolyHeight(path[0], result, ref h);
				result.Y = h;
				pos = result;
				return true;
			}

			return false;
		}
Exemple #47
0
		public int FindCorners(Vector3[] cornerVerts, int[] cornerFlags, PolyId[] cornerPolys, int maxCorners, NavMeshQuery navquery)
		{
			const float MinTargetDist = 0.01f;

			int numCorners = 0;
			navquery.FindStraightPath(pos, target, path, pathCount, cornerVerts, cornerFlags, cornerPolys, ref numCorners, maxCorners, 0);

			//prune points in the beginning of the path which are too close
			while (numCorners > 0)
			{
				if (((cornerFlags[0] & PathfindingCommon.STRAIGHTPATH_OFFMESH_CONNECTION) != 0) ||
					Vector3Extensions.Distance2D(cornerVerts[0], pos) > MinTargetDist)
					break;
				numCorners--;
				if (numCorners > 0)
				{
					for (int i = 0; i < numCorners; i++)
					{
						cornerFlags[i] = cornerFlags[i + 1];
						cornerPolys[i] = cornerPolys[i + 1];
						cornerVerts[i] = cornerVerts[i + 1];
					}
				}
			}

			//prune points after an off-mesh connection
			for (int i = 0; i < numCorners; i++)
			{
				if ((cornerFlags[i] & PathfindingCommon.STRAIGHTPATH_OFFMESH_CONNECTION) != 0)
				{
					numCorners = i + 1;
					break;
				}
			}

			return numCorners;
		}
Exemple #48
0
		/// <summary>
		/// Determines whether all the polygons in the path are valid
		/// </summary>
		/// <param name="maxLookAhead">The amount of polygons to examine</param>
		/// <param name="navquery">The NavMeshQuery</param>
		/// <returns>True if all valid, false if otherwise</returns>
		public bool IsValid(int maxLookAhead, NavMeshQuery navquery)
		{
			int n = Math.Min(pathCount, maxLookAhead);
			for (int i = 0; i < n; i++)
			{
				if (!navquery.IsValidPolyRef(path[i]))
					return false;
			}

			return true;
		}
    private bool GetSteerTarget(NavMeshQuery navMeshQuery, float[] startPos, float[] endPos, float minTargetDistance, long[] path, int pathSize, ref float[] steerPos, ref short steerPosFlag, ref long steerPosRef, ref float[] outPoints, ref int outPointCount)
    {
        int MaxSteerPoints = 3;
        float[] steerPath = new float[MaxSteerPoints * 3];
        short[] steerPathFlags = new short[MaxSteerPoints];
        long[] steerPathPolys = new long[MaxSteerPoints];

        int nSteerPath = 0;

        navMeshQuery.FindStraightPath(startPos, endPos, path, pathSize, ref steerPath, ref steerPathFlags,
                                      ref steerPathPolys, ref nSteerPath, MaxSteerPoints);

        if (nSteerPath == 0)
            return false;

        if (outPoints != null && outPointCount > 0)
        {
            outPointCount = nSteerPath;
            for (int i = 0; i < nSteerPath; i++)
            {
                Array.Copy(steerPath, i * 3, outPoints, i * 3, 3);
            }
        }

        int ns = 0;
        while (ns < nSteerPath)
        {
            if ((steerPathFlags[ns] & StraightPathOffMeshConnection) != 0 ||
                !InRange(steerPath[ns * 3 + 0], steerPath[ns * 3 + 1], steerPath[ns * 3 + 2], startPos, minTargetDistance, 1000.0f))
                break;
            ns++;
        }

        if (ns >= nSteerPath)
            return false;

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

        return true;
    }
Exemple #50
0
        /// <summary>
        /// Determines whether the polygon reference is a part of the NavMeshQuery.
        /// </summary>
        /// <param name="navquery">The NavMeshQuery</param>
        /// <returns>True if valid, false if not</returns>
        public bool IsValid(NavMeshQuery navquery)
        {
            if (numPolys == 0)
                return false;

            for (int i = 0; i < numPolys; i++)
            {
                if (!navquery.IsValidPolyRef(polys[i]))
                    return false;
            }

            return true;
        }
Exemple #51
0
        /// <summary>
        /// Examine polygons in the NavMeshQuery and add polygon edges
        /// </summary>
        /// <param name="reference">The starting polygon reference</param>
        /// <param name="pos">Current position</param>
        /// <param name="collisionQueryRange">Range to query</param>
        /// <param name="navquery">The NavMeshQuery</param>
        public void Update(PolyId reference, Vector3 pos, float collisionQueryRange, NavMeshQuery navquery)
        {
            const int MAX_SEGS_PER_POLY = PathfindingCommon.VERTS_PER_POLYGON;

            if (reference == PolyId.Null)
            {
                this.center = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
                this.segCount = 0;
                this.numPolys = 0;
                return;
            }

            this.center = pos;

            //first query non-overlapping polygons
            PolyId[] tempArray = new PolyId[polys.Length];
            navquery.FindLocalNeighbourhood(new NavPoint(reference, pos), collisionQueryRange, polys, tempArray, ref numPolys, MaxLocalPolys);

            //secondly, store all polygon edges
            this.segCount = 0;
            Segment[] segs = new Segment[MAX_SEGS_PER_POLY];
            int numSegs = 0;
            for (int j = 0; j < numPolys; j++)
            {
                tempArray = new PolyId[segs.Length];
                navquery.GetPolyWallSegments(polys[j], segs, tempArray, ref numSegs, MAX_SEGS_PER_POLY);
                for (int k = 0; k < numSegs; k++)
                {
                    //skip too distant segments
                    float tseg;
                    float distSqr = Distance.PointToSegment2DSquared(ref pos, ref segs[k].Start, ref segs[k].End, out tseg);
                    if (distSqr > collisionQueryRange * collisionQueryRange)
                        continue;
                    AddSegment(distSqr, segs[k]);
                }
            }
        }
Exemple #52
0
		/// <summary>
		/// Use a local area path search to try to reoptimize this corridor
		/// </summary>
		/// <param name="navquery">The NavMeshQuery</param>
		/// <returns>True if optimized, false if not</returns>
		public bool OptimizePathTopology(NavMeshQuery navquery)
		{
			if (pathCount < 3)
				return false;

			const int MaxIter = 32;
			const int MaxRes = 32;

			PolyId[] res = new PolyId[MaxRes];
			int numRes = 0;
			int tempInt = 0;
			navquery.InitSlicedFindPath(new NavPoint(path[0], pos), new NavPoint(path[pathCount - 1], target));
			navquery.UpdateSlicedFindPath(MaxIter, ref tempInt);
			bool status = navquery.FinalizedSlicedPathPartial(path, pathCount, res, ref numRes, MaxRes);

			if (status == true && numRes > 0)
			{
				pathCount = MergeCorridorStartShortcut(path, pathCount, maxPath, res, numRes); 
				return true;
			}

			return false;
		}