Пример #1
0
        //使用现有路径从起点到目标点建立标准的直接路径
        public NavStatus BuildStraightPath(NavmeshPoint start, NavmeshPoint goal, NavmeshQuery query)
        {
            int iStart = FindPolyRef(0, start.polyRef);
            int iGoal  = -1;

            if (iStart != -1)
            {
                iGoal = FindPolyRefReverse(iStart, goal.polyRef);
            }

            if (iGoal == -1)
            {
                return(NavStatus.Failure | NavStatus.InvalidParam);
            }
            //NavmeshQuery是直通C++的底层寻路

            Array.Clear(straightPoints, 0, straightPoints.Length);

            NavStatus status = query.GetStraightPath(start.point, goal.point
                                                     , path, iStart, iGoal - iStart + 1
                                                     , straightPoints, straightFlags, straightPath, out straightCount);

            if (straightCount == 0)
            {
                return(NavStatus.Failure);
            }

            return(status);
        }
Пример #2
0
        public static bool GetNavmeshPoint(Vector3 source, Vector3 extends, out NavmeshPoint point, NavmeshQueryFilter filter = null)
        {
            point = new NavmeshPoint();
            if (m_Map == null)
            {
                return(false);
            }
            var query = m_Map.Query;

            if (query == null)
            {
                return(false);
            }
            if (filter == null)
            {
                filter = m_Map.DefaultQueryFilter;
            }
            var status = query.GetNearestPoint(source, extends, filter, out point);

            if (NavUtil.Failed(status))
            {
                return(false);
            }
            return(true);
        }
Пример #3
0
 public static extern NavStatus dtqFindPath(IntPtr query
                                            , NavmeshPoint startPosition
                                            , NavmeshPoint endPosition
                                            , IntPtr filter
                                            , [In, Out] uint[] resultPath
                                            , ref int pathCount
                                            , int maxPath);
Пример #4
0
 public static extern NavStatus dtqFindDistanceToWall(IntPtr query
                                                      , NavmeshPoint position
                                                      , float searchRadius
                                                      , IntPtr filter
                                                      , ref float distance
                                                      , ref Vector3 closestPoint
                                                      , ref Vector3 normal);
Пример #5
0
        //从起点到终点的寻路
        //如果没找到路就返回-1
        public int PlanPath(NavmeshPoint start, NavmeshPoint end)
        {
            path.straightCount = 0;

            if (start.polyRef == 0 || end.polyRef == 0 || path == null)
            {
                return(-1);
            }

            if (start.polyRef == end.polyRef)
            {
                path.pathCount = 1;
                path.path[0]   = start.polyRef;
                navStatus      = NavStatus.Sucess;
                return(1);
            }

            if (path.FixPath(start.polyRef, end.polyRef))
            {
                navStatus = NavStatus.Sucess;
                return(path.pathCount);
            }

            //这是底层寻路的方法了
            navStatus = navGroup.query.FindPath(start, end, navGroup.filter, path.path, out path.pathCount);

            return(path.pathCount);
        }
Пример #6
0
        /// <summary>
        /// Handles planning when position feedback is required. (Replaces normal planning.)
        /// </summary>
        /// <returns>False on a critical failure.</returns>
        private bool HandlePositionFeedback()
        {
            // Important: Should only call this method once the desired position and planner goal
            // have been successfully constrained to the navigation mesh.

            // Make sure the path is still valid. Replan if needed.
            if (agent.PlanPath(agent.data.desiredPosition, agent.data.plannerGoal) <= 0)
            {
                // A critical failure.
                Debug.LogError(string.Format(
                                   "{0}: Path planning failed on position feedback. Position: {1}, Goal: {2}"
                                   , agent.transform.name
                                   , agent.data.desiredPosition.ToString()
                                   , agent.data.plannerGoal.ToString()));

                return(false);
            }

            agent.RemoveFromCrowd();
            agent.AddToCrowd(agent.data.desiredPosition.point);

            // Next assignment will usually force crowd target replanning.
            mTarget = agent.data.desiredPosition;

            // Since the path is known to be good, setting the local
            // target should never fail.
            return(SetLocalTarget());
        }
Пример #7
0
        /// <summary>
        /// Builds a straight path and gets the point farthest along the path that does not exceed
        /// the specified maximum number of polygons.
        /// </summary>
        /// <remarks>
        /// <para>Limits:</para>
        /// <ul>
        /// <li>The path must exist and both the start and goal points must be within the path.</li>
        /// <li>
        /// The goal's polygon reference must be in or after the start points polygon reference.
        /// </li>
        /// </ul>
        /// <para>
        /// <b>Special Case:</b>The result will exceed <paramref name="maxLength"/> if the
        /// first straight path point is greater than <paramref name="maxLength"/> from the start
        /// point.
        /// </para>
        /// </remarks>
        /// <param name="start">The start point within the current path.</param>
        /// <param name="goal">The end point located in or after the start point polygon.</param>
        /// <param name="maxLength">
        /// The maximum allowed number of polygons between the start and target. [Limit: >= 1]
        /// </param>
        /// <param name="target">The resulting target point.</param>
        /// <returns>The straight path index of the target point, or -1 on error.</returns>
        public int GetLocalTarget(NavmeshPoint start, NavmeshPoint goal, int maxLength
                                  , NavmeshQuery query
                                  , out NavmeshPoint target)
        {
            if (NavUtil.Failed(BuildStraightPath(start, goal, query)))
            {
                target = new NavmeshPoint();
                return(-1);
            }

            int targetIndex = straightCount;  // Will be decremented.
            int iStart      = FindPolyRef(0, start.polyRef);

            // Start at the end of the straight path and search back toward
            // the start until the number of polygons is less than
            // maxLength.
            uint targetRef = 0;

            do
            {
                targetIndex--;

                targetRef = (straightPath[targetIndex] == 0 ?
                             goal.polyRef : straightPath[targetIndex]);
            }while (FindPolyRefReverse(iStart, targetRef) - iStart + 1
                    > maxLength &&
                    targetIndex > 0);

            target = new NavmeshPoint(targetRef, straightPoints[targetIndex]);

            return(targetIndex);
        }
Пример #8
0
        //给出目标进行移动的方法
        private void MoveTo(NavmeshPoint goal, bool ignoreGoalRotation)
        {
            if (mNavAgent == null)
            {
                return;
            }

            goal = mNavAgent.GetPointSearch(goal);

            if (goal.polyRef == 0)
            {
                return;
            }

            mNavAgent.flags     &= ~NavFlag.GoalIsDynamic;
            mNavAgent.targetMode = mNavAgent.ChangeMode();
            mNavAgent.goal       = goal;

            if (ignoreGoalRotation)
            {
                mNavAgent.flags = (mNavAgent.flags | NavFlag.HasNewGoal) & ~NavFlag.GoalRotationEnabled;
            }
            else
            {
                mNavAgent.flags |= (NavFlag.HasNewGoal | NavFlag.GoalRotationEnabled);
            }
        }
Пример #9
0
 public static extern bool dtpcMoveOverOffmeshConnection(IntPtr corridor
                                                         , uint offMeshConRef
                                                         , [In, Out] uint[] refs // size 2
                                                         , ref Vector3 startPos
                                                         , ref Vector3 endPos
                                                         , ref NavmeshPoint resultPos
                                                         , IntPtr navquery);
Пример #10
0
        /// <summary>
        /// Move to the goal using the standard navigation mode.
        /// </summary>
        /// <param name="goal">The goal.</param>
        /// <param name="rangeType">The range check type.</param>
        /// <param name="ignoreGoalRotation">
        /// True if the final agent rotation does not matter.
        /// </param>
        /// <returns>True if the move request succeeded.</returns>
        public bool MoveTo(NavmeshPoint goal, RangeType rangeType, bool ignoreGoalRotation)
        {
            goal = agent.GetPointSearch(goal);

            if (goal.polyRef == 0)
            {
                return(false);
            }

            agent.data.flags     &= ~NavFlag.GoalIsDynamic;
            agent.data.targetMode = agent.ChooseMoveToMode();
            agent.data.goal       = goal;
            agent.data.goalType   = rangeType;

            if (ignoreGoalRotation)
            {
                agent.data.flags =
                    (agent.data.flags | NavFlag.HasNewGoal) & ~NavFlag.GoalRotationEnabled;
            }
            else
            {
                agent.data.flags |= (NavFlag.HasNewGoal | NavFlag.GoalRotationEnabled);
            }

            // Forces evaluation during next upate.
            mAtGoal = false;

            PostEvent(NavEventType.NewGoal);

            return(true);
        }
Пример #11
0
        private bool HandlePlanning(bool retargetPos, bool retargetGoal)
        {
            /*
             * Design notes:
             *
             * Tries to do a corridor move on the position and/or target.
             * A replan is only triggered if the move(s) fail to reach the desired polygon(s).
             *
             * It is important to note that the replan may fail to reach the goal.  But that is a
             * problem for the AI, not the planner.
             */

            bool needsFullReplan = false;

            // Convenience vars.  Only used for input.  Not updated.
            NavmeshPoint goal = agent.data.plannerGoal;
            NavmeshPoint pos  = agent.data.desiredPosition;

            PathCorridor corridor = agent.corridor;

            if (retargetGoal && retargetPos)
            {
                corridor.Move(pos.point, goal.point);
                retargetGoal = (goal.polyRef != corridor.Target.polyRef ||
                                pos.polyRef != corridor.Position.polyRef);
            }
            else if (retargetPos)
            {
                corridor.MovePosition(pos.point);
                needsFullReplan = (pos.polyRef != corridor.Position.polyRef);
            }
            else if (retargetGoal)
            {
                corridor.MoveTarget(goal.point);
                needsFullReplan = (goal.polyRef != corridor.Target.polyRef);
            }

            if (needsFullReplan)
            {
                // Debug.Log("Full Replan");
                if (agent.PlanCorridor(pos, goal) <= 0)
                {
                    Debug.LogError(agent.transform.name + ": Could not replan corridor.");
                    return(false);
                }
            }
            else if (retargetPos || retargetGoal)
            {
                // Debug.Log("Optimize Only");
                // Any chagnes are likely to be larger than normal.  So force an optimization.
                agent.corridor.OptimizePathTopology(true);
                mOptimizationTimer = OptimizationFrequency;
            }

            agent.data.desiredPosition = agent.corridor.Position;
            agent.data.plannerGoal     = agent.corridor.Target;

            return(true);
        }
Пример #12
0
 public static extern NavStatus dtqMoveAlongSurface(IntPtr query
                                                    , NavmeshPoint startPosition
                                                    , [In] ref Vector3 endPosition
                                                    , IntPtr filter
                                                    , ref Vector3 resultPosition
                                                    , [In, Out] uint[] visitedPolyRefs
                                                    , ref int visitedCount
                                                    , int maxVisited);
Пример #13
0
 private bool Follow(NavmeshPoint pt)
 {
     if (!IsInited || !NavMeshMap.IsVaild)
     {
         return(false);
     }
     return(m_Agent.RequestMoveTarget(pt));
 }
Пример #14
0
 public static extern int dtpcMoveTargetPosition(IntPtr corridor
                                                 , [In] ref Vector3 npos
                                                 , ref NavmeshPoint pos
                                                 , [In, Out] Vector3[] cornerVerts
                                                 , [In, Out] WaypointFlag[] cornerFlags
                                                 , [In, Out] uint[] cornerPolys
                                                 , int maxCorners
                                                 , IntPtr navquery
                                                 , IntPtr filter);
Пример #15
0
        public void Update()
        {
            if (mPolyRefs.HandleResize())
            {
                mStraightPath  = new Vector3[mPolyRefs.MaxElementCount];
                mVisitedCount  = 0;
                mStraightCount = 0;
            }

            if (Input.GetKeyDown(StdButtons.SelectA) ||
                Input.GetKey(StdButtons.SelectB))
            {
                Vector3      trasha;
                string       trashb;
                NavmeshPoint point;

                QEUtil.SearchResult searchResult =
                    QEUtil.HandleStandardPolySearch(mHelper, out trasha, out point, out trashb);

                if ((searchResult & QEUtil.SearchResult.HitNavmesh) == 0)
                {
                    return;
                }

                if (mPosition.polyRef == 0 || Input.GetKey(StdButtons.SelectB))
                {
                    mPosition     = point;
                    mGoal.polyRef = 0;
                }
                else
                {
                    mGoal = point;
                }

                mVisitedCount  = 0;
                mStraightCount = 0;
            }

            if (mVisitedCount == 0 &&
                mPosition.polyRef != 0 &&
                mGoal.polyRef != 0)
            {
                NavStatus status = mHelper.query.MoveAlongSurface(mPosition, mGoal.point
                                                                  , mHelper.filter
                                                                  , out mTarget.point, mPolyRefs.buffer, out mVisitedCount);

                mMessages = "MoveAlongSurface: " + status.ToString();

                if (mVisitedCount > 0)
                {
                    mHelper.query.GetStraightPath(mPosition.point, mTarget.point
                                                  , mPolyRefs.buffer, 0, mVisitedCount
                                                  , mStraightPath
                                                  , null, null, out mStraightCount);
                }
            }
        }
Пример #16
0
 public static extern NavStatus dtqRaycast(IntPtr query
                                           , NavmeshPoint startPosition
                                           , [In] ref Vector3 endPosition
                                           , IntPtr filter
                                           , ref float hitParameter
                                           , ref Vector3 hitNormal
                                           , [In, Out] uint[] path
                                           , ref int pathCount
                                           , int maxPath);
Пример #17
0
        //这个方法是真的移动计划的移动方法
        //根据路线进行移动(注意,这个Agent目标移动数据的修改)
        private bool HandlePlanning(bool retargetPos, bool retargetGoal)
        {
            bool needsFullReplan = false;
            //获取记录下来的这些信息
            NavmeshPoint goal = theAgent.plannerGoal;
            NavmeshPoint pos  = theAgent.desiredPosition;
            //获取路线引用
            PathCorridor corridor = theAgent.corridor;

            if (retargetGoal && retargetPos)
            {
                //此处调用CritterAI的PathCorridor,进而调用PathCorridorEx走recast
                //从当前的位置转移到希望运动到的位置,另外将目标移动到希望移动到的目标
                corridor.Move(pos.point, goal.point);
                retargetGoal = (goal.polyRef != corridor.Target.polyRef || pos.polyRef != corridor.Position.polyRef);
            }
            else if (retargetPos)
            {
                //此处调用CritterAI的PathCorridor,进而调用PathCorridorEx走recast
                //从当前的位置转移到希望运动到的位置
                corridor.MovePosition(pos.point);
                needsFullReplan = (pos.polyRef != corridor.Position.polyRef);
            }
            else if (retargetGoal)
            {
                //此处调用CritterAI的PathCorridor,进而调用PathCorridorEx走recast
                //将目标移动到希望移动到的目标
                corridor.MoveTarget(goal.point);
                needsFullReplan = (goal.polyRef != corridor.Target.polyRef);
            }

            if (needsFullReplan)
            {
                //完全重新计算路径
                if (theAgent.PlanCorridor(pos, goal) <= 0)
                {
                    //Debug.LogError(theAgent.transform.name + ": Could not replan corridor.");
                    SetPathInformation(pos, goal);
                    return(false);
                }
            }
            else if (retargetPos || retargetGoal)
            {
                //CritterAI作者加的强制优化
                theAgent.corridor.OptimizePathTopology(true);
                mOptimizationTimer = OptimizationFrequency;
            }

            //最后重新记录位置就可以了
            theAgent.desiredPosition = theAgent.corridor.Position;
            theAgent.plannerGoal     = theAgent.corridor.Target;


            return(true & SetPathInformation(theAgent.desiredPosition, theAgent.plannerGoal));
        }
Пример #18
0
        //是否有路径
        public bool HasPathToAim(Vector3 aim)
        {
            NavmeshPoint pt = GetNavPoint(aim);

            if (pt.polyRef == 0)
            {
                return(false);
            }

            return(true);
        }
Пример #19
0
 public static extern int dtpcSetCorridor(IntPtr corridor
                                          , [In] ref Vector3 target
                                          , [In] uint[] path
                                          , int pathCount
                                          , ref NavmeshPoint resultTarget
                                          , [In, Out] Vector3[] cornerVerts
                                          , [In, Out] WaypointFlag[] cornerFlags
                                          , [In, Out] uint[] cornerPolys
                                          , int maxCorners
                                          , IntPtr navquery
                                          , IntPtr filter);
Пример #20
0
        //外部的设定目标的方法
        public void SetDestination(Vector3 aimPoint)
        {
            NavmeshPoint pt = GetNavPoint(aimPoint);

            if (pt.polyRef == 0)
            {
                //Debug.Log("没有路线:"+aimPoint);
                return;
            }
            nowDestination = aimPoint;
            MoveTo(pt, true);
        }
Пример #21
0
        //调用底层的NavmeshQuery(导航网格查询)进行查询,这样就将设定的点与导航网格的点联系起来
        //如果该点没有多边形引用,则对其执行加宽搜索
        public NavmeshPoint GetPointSearch(NavmeshPoint point)
        {
            NavmeshPoint result = point;

            if (result.polyRef == 0)
            {
                navStatus = navGroup.query.GetNearestPoint(point.point, navGroup.extents, navGroup.filter, out result);
                if (result.polyRef == 0)
                {
                    navStatus = navGroup.query.GetNearestPoint(point.point, wideExtents, navGroup.filter, out result);
                }
            }
            return(result);
        }
Пример #22
0
        /// <summary>
        /// Starts up the planner.
        /// </summary>
        /// <returns>True on success.</returns>
        public bool Enter()
        {
            if (agent.navGroup.query == null)
            {
                return(false);
            }

            NavmeshPoint pos = agent.GetPointSearch(agent.data.position);

            if (pos.polyRef == 0)
            {
                Debug.LogError(string.Format(
                                   "{0}: Could not constrain position to navigation mesh. {1}"
                                   , agent.transform.name, pos.ToString()));

                return(false);
            }

            NavmeshPoint goal = agent.GetPointSearch(agent.data.goal);

            if (goal.polyRef == 0)
            {
                Debug.LogError(string.Format("{0}: Could not constrain goal to navigation mesh. {1}"
                                             , agent.transform.name, goal.ToString()));

                return(false);
            }

            agent.RemoveFromCrowd();
            agent.SetCorridorAssets(true);
            agent.SetPathAssets(false);

            if (agent.PlanCorridor(pos, goal) <= 0)
            {
                Debug.LogError(string.Format("{0}: Could not plan corridor on enter."
                                             , agent.transform.name));

                agent.data.flags &= ~NavFlag.CorridorInUse;
                return(false);
            }

            agent.data.desiredPosition = agent.corridor.Position;
            agent.data.plannerGoal     = agent.corridor.Target;
            agent.data.flags          &= ~(NavFlag.HasNewPosition | NavFlag.HasNewGoal);

            mSpeed             = Mathf.Sqrt(agent.data.desiredSpeedSq);
            mOptimizationTimer = OptimizationFrequency;

            return(true);
        }
Пример #23
0
        /// <summary>
        /// Move straight to the goal, ignoring the navigation mesh.
        /// </summary>
        /// <param name="goal">The goal.</param>
        /// <param name="goalRotation">The rotation at the end of the movement.</param>
        /// <param name="rangeType">The range check type.</param>
        /// <returns>True if the move request succeeded.</returns>
        public void MoveStraightTo(NavmeshPoint goal, Quaternion goalRotation, RangeType rangeType)
        {
            agent.data.flags       &= ~NavFlag.GoalIsDynamic;
            agent.data.targetMode   = NavMode.MoveToLocal;
            agent.data.goal         = goal;
            agent.data.goalRotation = goalRotation;
            agent.data.goalType     = rangeType;
            agent.data.flags       |= (NavFlag.HasNewGoal | NavFlag.GoalRotationEnabled);

            // Forces evaluation during next upate.
            mAtGoal = false;

            PostEvent(NavEventType.NewGoal);
        }
Пример #24
0
        //从池子里面获取通道,如果没有就需要建立一个(目前都是在NavAgent里面处理的)
        public PathCorridor GetCorridor(NavmeshPoint position, NavmeshQuery query, NavmeshQueryFilter filter)
        {
            if (mCorridors.Count > 0)
            {
                PathCorridor corr = mCorridors.Pop();

                if (PathCorridor.LoadLocals(corr, position, query, filter))
                {
                    return(corr);
                }

                return(null);
            }
            return(new PathCorridor(mMaxPathSize, mMaxStraightPathSize, query, filter));
        }
Пример #25
0
        //实际上这是一个不断开闭的过程
        //循环过程中也会不断Enter
        public override bool Enter()
        {
            if (theAgent.navGroup.query == null)
            {
                return(false);
            }

            //在导航网格上找到自己的位置
            NavmeshPoint pos = theAgent.GetPointSearch(theAgent.position);

            if (pos.polyRef == 0)
            {
                //Debug.LogError(string.Format("{0}: Could not constrain position to navigation mesh. {1}", theAgent.transform.name, pos.ToString()));
                return(false);
            }

            //在导航网格上找到目标的位置
            NavmeshPoint goal = theAgent.GetPointSearch(theAgent.goal);

            if (goal.polyRef == 0)
            {
                //Debug.LogError(string.Format("{0}: Could not constrain goal to navigation mesh. {1}", theAgent.transform.name, goal.ToString()));
                return(false);
            }

            theAgent.RemoveFromCrowd();
            theAgent.SetCorridorAssets(true);
            theAgent.SetPathAssets(true);

            //agent自己寻路,发现没有路就报错
            if (theAgent.PlanCorridor(pos, goal) <= 0)
            {
                //Debug.LogError(string.Format("{0}: Could not plan corridor on enter.", theAgent.transform.name));
                theAgent.flags &= ~NavFlag.CorridorInUse;
                return(false);
            }

            //存储寻路之后的结果
            theAgent.desiredPosition = theAgent.corridor.Position;
            theAgent.plannerGoal     = theAgent.corridor.Target;
            theAgent.flags          &= ~(NavFlag.HasNewPosition | NavFlag.HasNewGoal);

            //设定速度和重置计数器
            mSpeed             = Mathf.Sqrt(theAgent.desiredSpeedSq);
            mOptimizationTimer = OptimizationFrequency;

            return(true);
        }
Пример #26
0
        /// <summary>
        /// Starts up the planner.
        /// </summary>
        /// <returns>True if successful.</returns>
        public bool Enter()
        {
            if (agent == null || agent.navGroup.query == null || agent.navGroup.crowd == null)
            {
                // Agent in invalid state.
                return(false);
            }

            NavmeshPoint pos = agent.GetPointSearch(agent.data.position);

            if (pos.polyRef == 0)
            {
                Debug.LogError(string.Format(
                                   "{0}: Could not constrain position to navigation mesh. {1}"
                                   , agent.transform.name, pos.ToString()));

                return(false);
            }

            NavmeshPoint goal = agent.GetPointSearch(agent.data.goal);

            if (goal.polyRef == 0)
            {
                Debug.LogError(string.Format("{0}: Could not constrain goal to navigation mesh. {1}"
                                             , agent.transform.name, goal.ToString()));

                return(false);
            }

            if (agent.AddToCrowd(pos.point) == null)
            {
                Debug.LogError(string.Format("{0}: Could not add agent to the crowd."
                                             , agent.transform.name));

                return(false);
            }

            agent.data.desiredPosition = pos;
            agent.data.plannerGoal     = goal;

            agent.data.flags &= ~(NavFlag.HasNewPosition | NavFlag.HasNewGoal);

            agent.SetCorridorAssets(false);
            agent.SetPathAssets(true);

            return(HandlePositionFeedback());
        }
Пример #27
0
        public void SimUpdate(AgentContext context)
        {
            if (state != TaskState.Active)
            {
                return;
            }

            NavmeshPoint pt = context.navCon.GetNavPoint(target.position);

            if (pt.polyRef == 0)
            {
                // Not a valid target.
                return;
            }

            context.navCon.MoveTo(pt, RangeType.At, true);
        }
Пример #28
0
        public List <Waypoint> GenerateWaypointsBetweenTwoPoints(Navmesh navmesh, Vector3 startPos, Vector3 endPos)
        {
            List <Waypoint> waypoints = new List <Waypoint>();

            NavmeshQuery query;
            var          status = NavmeshQuery.Create(navmesh, 1024, out query);

            if (!NavUtil.Failed(status))
            {
                org.critterai.Vector3 navStartPointVect;
                org.critterai.Vector3 navEndPointVect;
                var navStartPointStatus = query.GetNearestPoint(1, new org.critterai.Vector3(startPos.x, startPos.y, startPos.z), out navStartPointVect);
                var navEndPointStatus   = query.GetNearestPoint(1, new org.critterai.Vector3(startPos.x, startPos.y, startPos.z), out navEndPointVect);
                if (navStartPointStatus == NavStatus.Sucess && navEndPointStatus == NavStatus.Sucess)
                {
                    NavmeshPoint navStartPoint = new NavmeshPoint(1, new org.critterai.Vector3(startPos.x, startPos.y, startPos.z));
                    NavmeshPoint navEndPoint   = new NavmeshPoint(1, new org.critterai.Vector3(endPos.x, endPos.y, endPos.z));

                    uint[] path = new uint[1024];
                    int    pathCount;
                    status = query.FindPath(navStartPoint, navEndPoint, new NavmeshQueryFilter(), path, out pathCount);
                    if (!NavUtil.Failed(status))
                    {
                        const int MaxStraightPath = 4;
                        int       wpCount;
                        org.critterai.Vector3[] wpPoints = new org.critterai.Vector3[MaxStraightPath];
                        uint[] wpPath = new uint[MaxStraightPath];

                        WaypointFlag[] wpFlags = new WaypointFlag[MaxStraightPath];
                        status = query.GetStraightPath(navStartPoint.point, navEndPoint.point
                                                       , path, 0, pathCount, wpPoints, wpFlags, wpPath
                                                       , out wpCount);
                        if (!NavUtil.Failed(status) && wpCount > 0)
                        {
                            foreach (var wp in wpPoints)
                            {
                                Mogre.Vector3 wayPointPos = new Vector3(wp.x, wp.y, wp.z);
                                waypoints.Add(new Waypoint(wayPointPos, new Vector3()));
                            }
                        }
                    }
                }
            }

            return(waypoints);
        }
Пример #29
0
        /// <summary>
        /// Adjust the position of an existing follow goal.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Expected to be called frequently. Problems can occur if the goal delta is too large.
        /// </para>
        /// <para>
        /// Must be in follow mode. (See: <see cref="Follow"/>)
        /// </para>
        /// <para>
        /// Will not trigger a 'new goal' event.
        /// </para>
        /// </remarks>
        /// <param name="goal">The adjusted goal.</param>
        /// <returns>True if successful.</returns>
        public bool AdjustFollow(NavmeshPoint goal)
        {
            goal = agent.GetPointSearch(goal);

            if (goal.polyRef == 0 || (agent.data.flags & NavFlag.GoalIsDynamic) == 0)
            {
                // Invalid request.
                return(false);
            }

            agent.data.goal = goal;

            // Always force evaluation during next upate.
            mAtGoal = false;

            return(true);
        }
Пример #30
0
        /// <summary>
        /// Starts up the planner.
        /// </summary>
        /// <returns>True if successful.</returns>
        public bool Enter()
        {
            if (agent == null || agent.navGroup.query == null || agent.navGroup.crowd == null)
            {
                return(false);
            }

            NavmeshPoint pos = agent.GetPointSearch(agent.data.position);

            if (pos.polyRef == 0)
            {
                Debug.LogError(string.Format(
                                   "{0}: Could not constrain position to navigation mesh. {1}"
                                   , agent.transform.name, pos.ToString()));

                return(false);
            }

            agent.RemoveFromCrowd();

            CrowdAgentParams config = agent.crowdConfig;

            config.maxSpeed = 0;

            agent.crowdAgent =
                agent.navGroup.crowd.AddAgent(agent.data.plannerGoal.point, config);

            if (agent.crowdAgent == null)
            {
                Debug.LogError(string.Format("{0}: Could not add agent to the crowd."
                                             , agent.transform.name));

                return(false);
            }

            agent.data.flags &= ~NavFlag.CrowdConfigUpdated;

            agent.data.desiredPosition = agent.data.position;
            agent.data.desiredSpeedSq  = 0;
            agent.data.desiredVelocity = Vector3.zero;

            agent.SetCorridorAssets(false);
            agent.SetPathAssets(false);

            return(true);
        }
Пример #31
0
 public static extern bool dtcAdjustMoveTarget(IntPtr crowd
     , int agentIndex
     , NavmeshPoint position);
Пример #32
0
 public static extern NavStatus dtqFindPathExt(IntPtr query
     , ref NavmeshPoint startPosition
     , ref NavmeshPoint endPosition
     , [In] ref Vector3 extents
     , IntPtr filter
     , [In, Out] uint[] resultPath
     , ref int pathCount
     , int maxPath);
Пример #33
0
 public static extern NavStatus dtqMoveAlongSurface(IntPtr query
     , NavmeshPoint startPosition
     , [In] ref Vector3 endPosition
     , IntPtr filter
     , ref Vector3 resultPosition
     , [In, Out] uint[] visitedPolyRefs
     , ref int visitedCount
     , int maxVisited);
Пример #34
0
 public static extern NavStatus dtqFindRandomPointCircle(IntPtr query
     , NavmeshPoint start
     , float radius
     , IntPtr filter
     , ref NavmeshPoint randomPt);
 public static extern bool dtpcMoveOverOffmeshConnection(IntPtr corridor
     , uint offMeshConRef
     , [In, Out] uint[] refs // size 2
     , ref Vector3 startPos
     , ref Vector3 endPos
     , ref NavmeshPoint resultPos
     , IntPtr navquery);
Пример #36
0
        /// <summary>
        /// Finds a path from the start point to the end point using the <see cref="path"/> object.
        /// </summary>
        /// <remarks>
        /// <para
        /// ><b>Warning</b>: The path object must be available before calling this method.
        /// </para>
        /// <para>
        /// This method will perform full planning only if <paramref name="start"/> or 
        /// <paramref name="end"/> is outside the existing path.
        /// </para>
        /// <para>
        /// The input points are all expected to be valid. (E.g. polyRef != 0)
        /// </para>
        /// </remarks>
        /// <param name="start">
        /// A valid navigation mesh point representing the start of the path.
        /// </param>
        /// <param name="end">
        /// A valid navigation mesh point representing the end of the path.
        /// </param>
        /// <returns>The length of the path, or -1 on failure.</returns>   
        public int PlanPath(NavmeshPoint start, NavmeshPoint end)
        {
            path.straightCount = 0;

            if (start.polyRef == 0 || end.polyRef == 0 || path == null)
                return -1;

            if (start.polyRef == end.polyRef)
            {
                // Debug.Log("Replan Path: Points in same poly.");
                path.pathCount = 1;
                path.path[0] = start.polyRef;
                data.navStatus = NavStatus.Sucess;
                return 1;
            }

            if (path.FixPath(start.polyRef, end.polyRef))
            {
                // Debug.Log("Replan Path: Fixed existing path");
                data.navStatus = NavStatus.Sucess;
                return path.pathCount;
            }

            // Debug.Log("Replace Path: Full query.");
            data.navStatus = navGroup.query.FindPath(start
                , end
                , navGroup.filter
                , path.path
                , out path.pathCount);

            return path.pathCount;
        }
Пример #37
0
        /// <summary>
        /// Builds a standard straight path from the start to the goal point using the exiting path.
        /// </summary>
        /// <remarks>
        /// <para>Limits:</para>
        /// <ul>
        /// <li>The path must exist and both the start and goal points must be within the path.</li>
        /// <li>
        /// The goal's polygon reference must be in or after the start points polygon reference.
        /// </li>
        /// </ul>
        /// </remarks>
        /// <param name="start">The start point.</param>
        /// <param name="goal">The goal point.</param>
        /// <returns>The status of the operation.</returns>
        public NavStatus BuildStraightPath(NavmeshPoint start, NavmeshPoint goal, NavmeshQuery query)
        {
            int iStart = FindPolyRef(0, start.polyRef);
            int iGoal = -1;

            if (iStart != -1)
                iGoal = FindPolyRefReverse(iStart, goal.polyRef);

            if (iGoal == -1)
                return (NavStatus.Failure | NavStatus.InvalidParam);

            NavStatus status = query.GetStraightPath(start.point, goal.point
                , path, iStart, iGoal - iStart + 1
                , straightPoints, straightFlags, straightPath, out straightCount);

            if (straightCount == 0)
                return NavStatus.Failure;

            return status;
        }
Пример #38
0
        public static extern NavStatus dtqFindDistanceToWall(IntPtr query
            , NavmeshPoint position
            , float searchRadius
	        , IntPtr filter
	        , ref float distance
            , ref Vector3 closestPoint
            , ref Vector3 normal);
Пример #39
0
        /// <summary>
        /// Uses the long distance path to determine the best target and, if necessary, feeds it 
        /// to the crowd manager.
        /// </summary>
        /// <returns>False if a target could not be determined. (Agent wandered outside 
        /// current path.)</returns>
        private bool SetLocalTarget()
        {
            mGoalInRange = false;

            NavmeshPoint target;

            int targetIndex = agent.path.GetLocalTarget(
                agent.data.desiredPosition, agent.data.plannerGoal
                , 32     // TODO: Make configurable.
                , agent.navGroup.query
                , out target);

            if (targetIndex == -1)
            {
                // Position or goal not in current path. (Not necessarily an error.) May have been
                // caused by the crowd manager, which has its own path planning.
                return false;
            }
            else if (target.point != mTarget.point)
            {
                // New target.  Send to crowd manager.
                if (mAtGoalState != StateNormal)
                {
                    // Assume that the agent is no longer at the goal.
                    agent.data.flags |= NavFlag.CrowdConfigUpdated;

                    if (mAtGoalState != StateNormal)
                        TransitionToNormalGoalState();
                }

                agent.crowdAgent.RequestMoveTarget(target);
            }

            mTarget = target;
            mGoalInRange = (mTarget.point == agent.data.plannerGoal.point);

            // Debug.LogWarning(mTarget.ToString() + ", " + mGoalInRange);

            return true;
        }
Пример #40
0
        /// <summary>
        /// Handles planning when position feedback is required. (Replaces normal planning.)
        /// </summary>
        /// <returns>False on a critical failure.</returns>
        private bool HandlePositionFeedback()
        {
            // Important: Should only call this method once the desired position and planner goal
            // have been successfully constrained to the navigation mesh.

            // Make sure the path is still valid. Replan if needed.
            if (agent.PlanPath(agent.data.desiredPosition, agent.data.plannerGoal) <= 0)
            {
                // A critical failure.
                Debug.LogError(string.Format(
                    "{0}: Path planning failed on position feedback. Position: {1}, Goal: {2}"
                    , agent.transform.name
                    , agent.data.desiredPosition.ToString()
                    , agent.data.plannerGoal.ToString()));

                return false;
            }

            agent.RemoveFromCrowd();
            agent.AddToCrowd(agent.data.desiredPosition.point);

            // Next assignment will usually force crowd target replanning.
            mTarget = agent.data.desiredPosition;

            // Since the path is known to be good, setting the local
            // target should never fail.
            return SetLocalTarget();
        }
Пример #41
0
        public static extern NavStatus dtqFindNearestPoly(IntPtr query
            , [In] ref Vector3 position
            , [In] ref Vector3 extents
		    , IntPtr filter
		    , ref NavmeshPoint nearest);
Пример #42
0
        /// <summary>
        /// Builds a straight path and gets the point farthest along the path that does not exceed 
        /// the specified maximum number of polygons.
        /// </summary>
        /// <remarks>
        /// <para>Limits:</para>
        /// <ul>
        /// <li>The path must exist and both the start and goal points must be within the path.</li>
        /// <li>
        /// The goal's polygon reference must be in or after the start points polygon reference.
        /// </li>
        /// </ul>
        /// <para>
        /// <b>Special Case:</b>The result will exceed <paramref name="maxLength"/> if the 
        /// first straight path point is greater than <paramref name="maxLength"/> from the start 
        /// point.
        /// </para>
        /// </remarks>
        /// <param name="start">The start point within the current path.</param>
        /// <param name="goal">The end point located in or after the start point polygon.</param>
        /// <param name="maxLength">
        /// The maximum allowed number of polygons between the start and target. [Limit: >= 1]
        /// </param>
        /// <param name="target">The resulting target point.</param>
        /// <returns>The straight path index of the target point, or -1 on error.</returns>
        public int GetLocalTarget(NavmeshPoint start, NavmeshPoint goal, int maxLength
            , NavmeshQuery query
            , out NavmeshPoint target)
        {
            if (NavUtil.Failed(BuildStraightPath(start, goal, query)))
            {
                target = new NavmeshPoint();
                return -1;
            }

            int targetIndex = straightCount;  // Will be decremented.
            int iStart = FindPolyRef(0, start.polyRef);

            // Start at the end of the straight path and search back toward
            // the start until the number of polygons is less than
            // maxLength.
            uint targetRef = 0;
            do
            {
                targetIndex--;

                targetRef = (straightPath[targetIndex] == 0 ?
                        goal.polyRef : straightPath[targetIndex]);
            }
            while (FindPolyRefReverse(iStart, targetRef) - iStart + 1
                    > maxLength
                && targetIndex > 0);

            target = new NavmeshPoint(targetRef, straightPoints[targetIndex]);

            return targetIndex;
        }
Пример #43
0
 /// <summary>
 /// Performs an widening search for the point if it does not have a polygon reference.
 /// </summary>
 /// <remarks>
 /// <para>
 /// A search will only be attempted if the point's polygon reference is zero.
 /// </para>
 /// <para>
 /// The result's polygon reference will remain zero if the search failed.
 /// </para>
 /// </remarks>
 /// <param name="point">A point that needs to be constrained to the navigation mesh.</param>
 /// <returns>The point, constrained to the navigation mesh.</returns>
 public NavmeshPoint GetPointSearch(NavmeshPoint point)
 {
     NavmeshPoint result = point;
     if (result.polyRef == 0)
     {
         data.navStatus = navGroup.query.GetNearestPoint(
             point.point, navGroup.extents, navGroup.filter, out result);
         if (result.polyRef == 0)
         {
             data.navStatus = navGroup.query.GetNearestPoint(
                 point.point , wideExtents, navGroup.filter , out result);
         }
     }
     return result;
 }
 public static extern void dtpcReset(IntPtr corridor
     , NavmeshPoint position);
Пример #45
0
        /// <summary>
        /// Finds a path from the start point to the end point and loads it into the corridor.
        /// </summary>
        /// <remarks>
        /// <para>
        /// <b>Warning</b>: The corridor must be available before calling this method.
        /// </para>
        /// <para>
        /// The input points are all expected to be valid. (E.g. polyRef != 0)
        /// </para>
        /// </remarks>
        /// <param name="start">
        /// A valid navigation mesh point representing the start of the path.
        /// </param>
        /// <param name="end">
        /// A valid navigation mesh point representing the end of the path.
        /// </param>
        /// <returns>The length of the path, or -1 on failure.</returns>
        public int PlanCorridor(NavmeshPoint start, NavmeshPoint end)
        {
            // Note: Don't try to re-use the current corridor.  Unlike
            // paths, the corridor is more likely to become malformed
            // over time.

            int pathCount;
            if (start.polyRef == 0 || end.polyRef == 0 || corridor == null)
                return -1;

            if (start.polyRef == end.polyRef)
            {
                corridor.Reset(start);
                corridor.MoveTarget(end.point);
                data.navStatus = NavStatus.Sucess;
                return 1;
            }
            else
            {
                data.navStatus = navGroup.query.FindPath(start
                    , end
                    , navGroup.filter
                    , agentGroup.pathBuffer
                    , out pathCount);
            }

            corridor.Reset(start);

            if (pathCount > 0)
            {
                corridor.SetCorridor(end.point
                    , agentGroup.pathBuffer
                    , pathCount);
            }

            return pathCount;
        }
 public static extern int dtpcMove(IntPtr corridor
     , [In] ref Vector3 npos
     , [In] ref Vector3 ntarget
     , ref NavmeshPoint pos
     , ref NavmeshPoint target
     , [In, Out] Vector3[] cornerVerts
     , [In, Out] WaypointFlag[] cornerFlags
     , [In, Out] uint[] cornerPolys
     , int maxCorners
     , IntPtr navquery
     , IntPtr filter);
Пример #47
0
        /// <summary>
        /// Gets a standard corridor from the pool. (Or creates one if none is available.)
        /// </summary>
        /// <remarks>
        /// <para>
        /// The corridor maximum path will equal <see cref="MaxPathSize"/>, and maximum corners 
        /// will equal <see cref="MaxStraightPathSize"/> .
        /// </para>
        /// </remarks>
        /// <param name="query">The query to assign to the corridor.</param>
        /// <param name="filter">The filter to assign to the corridor.</param>
        /// <returns>A standard corridor, or null on error.</returns>
        public PathCorridor GetCorridor(NavmeshPoint position, NavmeshQuery query, NavmeshQueryFilter filter)
        {
            if (mCorridors.Count > 0)
            {
                PathCorridor corr = mCorridors.Pop();

                if (PathCorridor.LoadLocals(corr, position, query, filter))
                    return corr;

                return null;
            }
            return new PathCorridor(mMaxPathSize, mMaxStraightPathSize, query, filter);
        }
Пример #48
0
 public static extern NavStatus dtqFindRandomPoint(IntPtr query
     , IntPtr filter
     , ref NavmeshPoint randomPt);
 public static extern int dtpcSetCorridor(IntPtr corridor
     , [In] ref Vector3 target
     , [In] uint[] path
     , int pathCount
     , ref NavmeshPoint resultTarget
     , [In, Out] Vector3[] cornerVerts
     , [In, Out] WaypointFlag[] cornerFlags
     , [In, Out] uint[] cornerPolys
     , int maxCorners
     , IntPtr navquery
     , IntPtr filter);
Пример #50
0
 public static extern NavStatus dtqGetPolyHeight(IntPtr query
     , NavmeshPoint position
     , ref float height);
Пример #51
0
 public static extern NavStatus dtqInitSlicedFindPath(IntPtr query
     , NavmeshPoint startPosition
     , NavmeshPoint endPosition
     , IntPtr filter);
Пример #52
0
        public static extern NavStatus dtqRaycast(IntPtr query
            , NavmeshPoint startPosition
            , [In] ref Vector3 endPosition
	        , IntPtr filter
	        , ref float hitParameter 
            , ref Vector3 hitNormal
            , [In, Out] uint[] path
            , ref int pathCount
            , int maxPath);