Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
        List <Entity> itemAttached;//Item that attached to character

        public CharacterController(
            Camera cam,
            NavmeshQuery query,
            Scene physicsScene,
            string meshName,
            ModCharacterSkinDfnXML skin,
            bool isBot,
            Mogre.Vector3 initPosition)
        {
            camera            = cam;
            this.controlled   = !isBot;
            itemAttached      = new List <Entity>();
            this.sceneMgr     = cam.SceneManager;
            charaMeshName     = meshName;
            this.physicsScene = physicsScene;
            physics           = physicsScene.Physics;
            cotrollerManager  = physics.ControllerManager;
            this.query        = query;
            setupBody(initPosition);
            if (controlled)
            {
                setupCamera(cam);
            }

            this.skin = skin;

            setupAnimations();
            setupPhysics();
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Immediately frees all unmanaged resources allocated by the object.
        /// </summary>
        public override void RequestDisposal()
        {
            // There are no managed or local allocations.
            if (root != IntPtr.Zero)
            {
                mFilter.RequestDisposal();
                mFilter = null;
                mGrid.Dispose();
                mGrid = null;
                mQuery.RequestDisposal();
                mQuery          = null;
                mNavmesh        = null;
                mMaxAgentRadius = -1;
                agentStates     = null;

                for (int i = 0; i < mAgents.Length; i++)
                {
                    if (mAgents[i] == null)
                    {
                        continue;
                    }
                    mAgents[i].Dispose();
                    mAgents[i] = null;
                }

                CrowdManagerEx.dtcDetourCrowdFree(root);
                root = IntPtr.Zero;
            }
        }
Ejemplo n.º 5
0
        private static Color GetStandardColor(uint polyRef, int polyArea, int colorId
                                              , NavmeshQuery query, uint[] markPolys, int markPolyCount)
        {
            Color result;

            if ((query != null && query.IsInClosedList(polyRef)) ||
                IsInList(polyRef, markPolys, markPolyCount) != -1)
            {
                result = polygonOverlayColor;
            }
            else
            {
                if (colorId == -1)
                {
                    if (polyArea == 0)
                    {
                        result = new Color(0, 0.75f, 1, surfaceAlpha);
                    }
                    else
                    {
                        result = ColorUtil.IntToColor(polyArea, surfaceAlpha);
                    }
                }
                else
                {
                    result = ColorUtil.IntToColor(colorId, surfaceAlpha);
                }
            }

            return(result);
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Copy constructor.
 /// </summary>
 /// <param name="copy">The group to copy.</param>
 /// <param name="cloneFilter">
 /// If true, the filter will be cloned. Otherwise it will be referenced.
 /// </param>
 public NavGroup(NavGroup copy, bool cloneFilter)
 {
     this.mesh    = copy.mesh;
     this.query   = copy.query;
     this.crowd   = copy.crowd;
     this.filter  = (cloneFilter ? copy.filter.Clone() : copy.filter);
     this.extents = copy.extents;
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Draws a debug visualization of the navigation mesh with the closed nodes highlighted.
        /// </summary>
        /// <param name="mesh">The mesh to draw.</param>
        /// <param name="query">The query which provides the list of closed nodes.</param>
        public static void Draw(Navmesh mesh, NavmeshQuery query)
        {
            int count = mesh.GetMaxTiles();

            for (int i = 0; i < count; i++)
            {
                Draw(mesh.GetTile(i), query, null, 0, i);
            }
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="mesh">The navigation mesh used by the query.</param>
 /// <param name="query">A navigation mesh query.</param>
 /// <param name="crowd">A crowd.</param>
 /// <param name="filter">The filter to use with the query.</param>
 /// <param name="extents">The extents to use with the query.</param>
 /// <param name="cloneFilter">
 /// If true, the filter will be cloned rather than referenced.
 /// </param>
 public NavGroup(Navmesh mesh, NavmeshQuery query, CrowdManager crowd
     , NavmeshQueryFilter filter, Vector3 extents
     , bool cloneFilter)
 {
     this.mesh = mesh;
     this.query = query;
     this.crowd = crowd;
     this.filter = (cloneFilter ? filter.Clone() : filter);
     this.extents = extents;
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="mesh">The navigation mesh used by the query.</param>
 /// <param name="query">A navigation mesh query.</param>
 /// <param name="crowd">A crowd.</param>
 /// <param name="filter">The filter to use with the query.</param>
 /// <param name="extents">The extents to use with the query.</param>
 /// <param name="cloneFilter">
 /// If true, the filter will be cloned rather than referenced.
 /// </param>
 public NavGroup(Navmesh mesh, NavmeshQuery query, CrowdManager crowd
                 , NavmeshQueryFilter filter, Vector3 extents
                 , bool cloneFilter)
 {
     this.mesh    = mesh;
     this.query   = query;
     this.crowd   = crowd;
     this.filter  = (cloneFilter ? filter.Clone() : filter);
     this.extents = extents;
 }
Ejemplo n.º 10
0
        public void Create(Navmesh navmesh)
        {
            this._navmesh = navmesh;            //一定要保存起来,Navmesh的析构函数会把非托管内存的指针清掉!!
            NavStatus status = NavmeshQuery.Create(navmesh, 2048, out this._query);

            if (status != NavStatus.Sucess)
            {
                LLogger.Error(status);
            }
        }
Ejemplo n.º 11
0
        public Pathfinder(Navmesh navMesh)
        {
            _navMesh = navMesh;
            _filter  = new NavmeshQueryFilter();

            if (NavUtil.Failed(NavmeshQuery.Create(_navMesh, 1000, out _query)))
            {
                throw new Exception("NavQuery failed");
            }

            _pathCorridor = new PathCorridor(1000, 1000, _query, _filter);
        }
Ejemplo n.º 12
0
 private void Clear()
 {
     if (m_Query != null)
     {
         m_Query.RequestDisposal();
         m_Query = null;
     }
     if (m_NavMesh != null)
     {
         m_NavMesh.RequestDisposal();
         m_NavMesh = null;
     }
 }
Ejemplo n.º 13
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));
        }
Ejemplo n.º 14
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);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <remarks>
        /// <para>
        /// <b>Important:</b> The <see cref="Reset"/> method must be called before the corridor
        /// can be used. (That is how the position is set.)
        /// </para>
        /// <para>
        /// Due to internal optimizations, the maximum number of detectable corners will be
        /// <c>(<paramref name="maxCorners"/> - 1)</c>.
        /// </para>
        /// <para>The query and filter parameters can be set to null.  This supports the ability
        /// to create pools of re-usable path corridor objects.  But it means that care needs to
        /// be taken not to use the corridor until query and filter objects have been set.
        /// See <see cref="ReleaseLocals"/> and <see cref="LoadLocals"/> for pool related utility
        /// functions.
        /// </para>
        /// </remarks>
        /// <param name="maxPathSize">
        /// The maximum path size that can be handled by the object. [Limit: >= 1]
        /// </param>
        /// <param name="maxCorners">
        /// The maximum number of corners the corner buffer can hold. [Limit: >= 2]
        /// </param>
        /// <param name="query">The query to be used by the corridor.</param>
        /// <param name="filter">The query filter to be used by the corridor.</param>
        public PathCorridor(int maxPathSize, int maxCorners
                            , NavmeshQuery query, NavmeshQueryFilter filter)
        {
            maxPathSize = Math.Max(1, maxPathSize);

            mRoot = PathCorridorEx.dtpcAlloc(maxPathSize);

            if (mRoot == IntPtr.Zero)
            {
                mMaxPathSize = 0;
                return;
            }

            mQuery       = query;
            mFilter      = filter;
            mMaxPathSize = maxPathSize;
            mCorners     = new CornerData(Math.Max(2, maxCorners));
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Sets the specified resources and resets the corridor.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method is useful when pooling path corridors for use by mulitple clients.
        /// </para>
        /// <para>
        /// See <see cref="Reset"/> for information on the effect of the reset.
        /// </para>
        /// <para>
        /// Existing references will be replaced by the new references.
        /// </para>
        /// <para>
        /// This method cannot be used to set references to null. Attempting to do so will result
        /// in a failure.
        /// </para>
        /// </remarks>
        /// <param name="corridor">The corridor to update.</param>
        /// <param name="position">The position to reset to corridor to.</param>
        /// <param name="query">The query object to use.</param>
        /// <param name="filter">The filter object to use.</param>
        /// <returns>True if successful.</returns>
        public static bool LoadLocals(PathCorridor corridor, NavmeshPoint position
                                      , NavmeshQuery query, NavmeshQueryFilter filter)
        {
            // Basic checks first.
            if (position.polyRef == 0 || corridor == null || query == null || filter == null)
            {
                return(false);
            }

            // Validate optional parameters.

            // Assign and reset.

            corridor.mQuery  = query;
            corridor.mFilter = filter;
            corridor.Reset(position);

            return(true);
        }
Ejemplo n.º 17
0
        private CrowdManager(IntPtr crowd, Navmesh navmesh, int maxAgents, float maxAgentRadius)
            : base(AllocType.External)
        {
            mMaxAgentRadius = maxAgentRadius;
            mNavmesh        = navmesh;

            root = crowd;

            mAgents     = new CrowdAgent[maxAgents];
            agentStates = new CrowdAgentCoreState[maxAgents];

            IntPtr ptr = CrowdManagerEx.dtcGetFilter(root);

            mFilter = new NavmeshQueryFilter(ptr, AllocType.ExternallyManaged);

            ptr   = CrowdManagerEx.dtcGetGrid(root);
            mGrid = new CrowdProximityGrid(ptr);

            ptr    = CrowdManagerEx.dtcGetNavMeshQuery(root);
            mQuery = new NavmeshQuery(ptr, true, AllocType.ExternallyManaged);
        }
Ejemplo n.º 18
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);
        }
Ejemplo n.º 19
0
 public void Dispose()
 {
     this._query   = null;
     this._navmesh = null;            //让gc调用析构函数
 }
Ejemplo n.º 20
0
    public void CreateQuery(float fMoveSpeed, float fTurnSpeed)
    {
        this.mTurnSpeed = fTurnSpeed;
        this.mMoveSpeed = fMoveSpeed;
        NavStatus status = NavmeshQuery.Create(navmesh, mMaxQueryNodes, out query);

        if ((status & NavStatus.Sucess) == 0)
        {
            Debug.LogError(
                fileName + ": Aborted initialization. Failed query creation: " + status.ToString());
            mCrowdManager = null;
            return;
        }

        mCrowdManager = CrowdManager.Create(mMaxCrowdAgents, mMaxAgentRadius, navmesh);
        if (mCrowdManager == null)
        {
            Debug.LogError(fileName + ": Aborted initialization. Failed crowd creation.");
        }

        CrowdAvoidanceParams mCrowdParam = CrowdAvoidanceParams.CreateStandardMedium();

        mCrowdManager.SetAvoidanceConfig(0, mCrowdParam);
        mCrowdAgentParams = new CrowdAgentParams();
        mCrowdAgentParams.avoidanceType       = 0;
        mCrowdAgentParams.collisionQueryRange = 3.2f;
        mCrowdAgentParams.height                = 1.8f;
        mCrowdAgentParams.maxAcceleration       = 8.0f;
        mCrowdAgentParams.maxSpeed              = this.mMoveSpeed;
        mCrowdAgentParams.pathOptimizationRange = 12.0f;
        mCrowdAgentParams.radius                = 1.0f;
        mCrowdAgentParams.separationWeight      = 2.0f;
        mCrowdAgentParams.updateFlags           = CrowdUpdateFlags.AnticipateTurns | CrowdUpdateFlags.ObstacleAvoidance | CrowdUpdateFlags.CrowdSeparation | CrowdUpdateFlags.OptimizeVis | CrowdUpdateFlags.OptimizeTopo;

        polyResult        = new uint[300];
        pointResult       = new Vector3[300];
        tileBufferPoints  = new Vector3[3000];
        pointResultBuffer = new Vector3[300];
        polyResultBuffer  = new uint[300];
        NavmeshTile tile  = navmesh.GetTile(0);
        int         count = tile.GetVerts(tileBufferPoints);

        Debug.Log("Tile " + tile.GetTileRef() + " count:" + count);
        if (count > 3000)
        {
            tileBufferPoints = new Vector3[count];
        }
        tileBufferRef = -1;

        //NavmeshPoly[] polys=new NavmeshPoly[3000];
        //int polyCount;
        //polyCount=tile.GetPolys(polys);
        //for (int i = 0; i < polyCount; i++)
        //{
        //    NavmeshPoly poly = polys[i];
        //    //if (poly.Type == NavmeshPolyType.OffMeshConnection)
        //    {
        //        Debug.Log("Poly" + i+"type"+poly.Type.ToString());
        //    }
        //}
    }
Ejemplo n.º 21
0
    public NavManager CreateManager()
    {
        if (!(mNavmeshData && NavmeshData.HasNavmesh))
        {
            Debug.LogError(name + ": Aborted initialization. Navigation mesh not available.");
            return(null);
        }

        if (!mAvoidanceSet || !mGroupsSettings)
        {
            Debug.LogError(
                name + ": Aborted initialization. Avoidance and/or agent groups not available.");
            return(null);
        }

        Navmesh      navmesh = NavmeshData.GetNavmesh();
        NavmeshQuery query;
        NavStatus    status = NavmeshQuery.Create(navmesh, mMaxQueryNodes, out query);

        if ((status & NavStatus.Sucess) == 0)
        {
            Debug.LogError(
                name + ": Aborted initialization. Failed query creation: " + status.ToString());
            return(null);
        }

        CrowdManager crowd = CrowdManager.Create(mMaxCrowdAgents, mMaxAgentRadius, navmesh);

        if (crowd == null)
        {
            Debug.LogError(name + ": Aborted initialization. Failed crowd creation.");
            return(null);
        }

        for (int i = 0; i < CrowdManager.MaxAvoidanceParams; i++)
        {
            crowd.SetAvoidanceConfig(i, mAvoidanceSet[i]);
        }

        NavGroup mGroup = new NavGroup(navmesh, query, crowd, crowd.QueryFilter, mExtents, false);

        int count = mGroupsSettings.GroupCount;
        Dictionary <byte, NavAgentGroup> mAgentGroups = new Dictionary <byte, NavAgentGroup>(count);

        for (int i = 0; i < count; i++)
        {
            byte          groupId;
            NavAgentGroup group =
                mGroupsSettings.CreateAgentGroup(i, mMaxPath, mMaxStraightPath, out groupId);

            group.angleAt         = mAngleAt;
            group.heightTolerance = mHeightTolerance;
            group.radiusAt        = mRadiusAt;
            group.radiusNear      = mRadiusNear;
            group.turnThreshold   = mTurnThreshold;

            mAgentGroups.Add(groupId, group);
        }

        return(NavManager.Create(mMaxAgents, mGroup, mAgentGroups));
    }
Ejemplo n.º 22
0
 /// <summary>
 /// Copy constructor.
 /// </summary>
 /// <param name="copy">The group to copy.</param>
 /// <param name="cloneFilter">
 /// If true, the filter will be cloned. Otherwise it will be referenced.
 /// </param>
 public NavGroup(NavGroup copy, bool cloneFilter)
 {
     this.mesh = copy.mesh;
     this.query = copy.query;
     this.crowd = copy.crowd;
     this.filter = (cloneFilter ? copy.filter.Clone() : copy.filter);
     this.extents = copy.extents;
 }
Ejemplo n.º 23
0
        //创作一个新的直接路径,并且沿路获取点
        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;
            int iStart      = FindPolyRef(0, start.polyRef);

            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);
        }
Ejemplo n.º 24
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;
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Draws a debug visualization of an individual navmesh tile.
        /// </summary>
        /// <remarks>
        /// <para>
        /// The tile will be checked to see if it is in use before it is drawn.  So there is no 
        /// need for caller to do so.
        /// </para>
        /// </remarks>
        private static void Draw(NavmeshTile tile
            , NavmeshQuery query, uint[] markPolys, int markPolyCount
            , int colorId)
        {
            NavmeshTileHeader header = tile.GetHeader();

            // Keep this check.  Less trouble for clients.
            if (header.polyCount < 1)
                return;

            DebugDraw.SimpleMaterial.SetPass(0);

            uint polyBase = tile.GetBasePolyRef();

            NavmeshPoly[] polys = new NavmeshPoly[header.polyCount];
            tile.GetPolys(polys);
             
            Vector3[] verts = new Vector3[header.vertCount];
            tile.GetVerts(verts);

            NavmeshDetailMesh[] meshes = 
                new NavmeshDetailMesh[header.detailMeshCount];
            tile.GetDetailMeshes(meshes);

            byte[] detailTris = new byte[header.detailTriCount * 4];
            tile.GetDetailTris(detailTris);

            Vector3[] detailVerts = new Vector3[header.detailVertCount];
            tile.GetDetailVerts(detailVerts);

            GL.Begin(GL.TRIANGLES);
            for (int i = 0; i < header.polyCount; i++)
            {
                NavmeshPoly poly = polys[i];

                if (poly.Type == NavmeshPolyType.OffMeshConnection)
                    continue;

                NavmeshDetailMesh mesh = meshes[i];

                Color color = GetStandardColor(polyBase | (uint)i
                    , poly.Area, colorId
                    , query, markPolys, markPolyCount);

                GL.Color(color);

                for (int j = 0; j < mesh.triCount; j++)
                {
                    int pTri = (int)(mesh.triBase + j) * 4;

                    for (int k = 0; k < 3; k++)
                    {
                        // Note: iVert and pVert refer to different
                        // arrays.
                        int iVert = detailTris[pTri + k];
                        if (iVert < poly.vertCount)
                        {
                            // Get the vertex from the main vertices.
                            int pVert = poly.indices[iVert];
                            GL.Vertex(verts[pVert]);
                        }
                        else
                        {
                            // Get the vertex from the detail vertices.
                            int pVert = (int)
                                (mesh.vertBase + iVert - poly.vertCount);
                            GL.Vertex(detailVerts[pVert]);
                        }
                    }
                }
            }
            GL.End();

            NavmeshLink[] links = new NavmeshLink[header.maxLinkCount];
            tile.GetLinks(links);

            GL.Begin(GL.LINES);

            DrawPolyBoundaries(header
                , polys
                , verts
                , meshes
                , detailTris
                , detailVerts
                , links
                , new Color(0, 0.2f, 0.25f, 0.13f)
                , true);

            DrawPolyBoundaries(header
                , polys
                , verts
                , meshes
                , detailTris
                , detailVerts
                , links
                , new Color(0.65f, 0.2f, 0, 0.9f)
                , false);

            if (header.connCount == 0)
            {
                GL.End();
                return;
            }

            NavmeshConnection[] conns = new NavmeshConnection[header.connCount];
            tile.GetConnections(conns);

            for (int i = 0; i < header.polyCount; i++)
            {
                NavmeshPoly poly = polys[i];

                if (poly.Type != NavmeshPolyType.OffMeshConnection)
                    continue;

                Color color = GetStandardColor(polyBase | (uint)i
                    , poly.Area, colorId
                    , query, markPolys, markPolyCount);

                // Note: Alpha of less than one doesn't look good because connections tend to
                // overlay a lot of geometry, resulting is off color transitions.
                color.a = 1;

                GL.Color(color);

                NavmeshConnection conn = conns[i - header.connBase];

			    Vector3 va = verts[poly.indices[0]];
			    Vector3 vb = verts[poly.indices[1]];

			    // Check to see if start and end end-points have links.
			    bool startSet = false;
			    bool endSet = false;
			    for (uint k = poly.firstLink; k != Navmesh.NullLink; k = links[k].next)
			    {
				    if (links[k].edge == 0)
					    startSet = true;
				    if (links[k].edge == 1)
					    endSet = true;
			    }
    			
                // For linked endpoints: Draw a line between on-mesh location and endpoint, 
                // and draw circle at the endpoint.
                // For un-linked endpoints: Draw a small red x-marker.

                if (startSet)
                {
                    GL.Vertex(va);
                    GL.Vertex(conn.endpoints[0]);
                    DebugDraw.AppendCircle(conn.endpoints[0], conn.radius);
                }
                else
                {
                    GL.Color(Color.red);
                    DebugDraw.AppendXMarker(conn.endpoints[0], 0.1f);
                    GL.Color(color);
                }

                if (endSet)
                {
                    GL.Vertex(vb);
                    GL.Vertex(conn.endpoints[1]);
                    DebugDraw.AppendCircle(conn.endpoints[1], conn.radius);
                }
                else
                {
                    GL.Color(Color.red);
                    DebugDraw.AppendXMarker(conn.endpoints[1], 0.1f);
                    GL.Color(color);
                }

                DebugDraw.AppendArc(conn.endpoints[0], conn.endpoints[1]
                    , 0.25f
                    , conn.IsBiDirectional ? 0.6f : 0
                    , 0.6f);
            }

            GL.End();
        }
Ejemplo n.º 26
0
        private static Color GetStandardColor(uint polyRef, int polyArea, int colorId
            , NavmeshQuery query, uint[] markPolys, int markPolyCount)
        {
            Color result;

            if ((query != null && query.IsInClosedList(polyRef))
                || IsInList(polyRef, markPolys, markPolyCount) != -1)
            {
                result = polygonOverlayColor;
            }
            else
            {
                if (colorId == -1)
                {
                    if (polyArea == 0)
                        result = new Color(0, 0.75f, 1, surfaceAlpha);
                    else
                        result = ColorUtil.IntToColor(polyArea, surfaceAlpha);
                }
                else
                    result = ColorUtil.IntToColor(colorId, surfaceAlpha);
            }

            return result;
        }
Ejemplo n.º 27
0
 /// <summary>
 /// Draws a debug visualization of the navigation mesh with the closed nodes highlighted.
 /// </summary>
 /// <param name="mesh">The mesh to draw.</param>
 /// <param name="query">The query which provides the list of closed nodes.</param>
 public static void Draw(Navmesh mesh, NavmeshQuery query)
 {
     int count = mesh.GetMaxTiles();
     for (int i = 0; i < count; i++)
     {
         Draw(mesh.GetTile(i), query, null, 0, i);
     }
 }
Ejemplo n.º 28
0
        /// <summary>
        /// Draws a debug visualization of an individual navmesh tile.
        /// </summary>
        /// <remarks>
        /// <para>
        /// The tile will be checked to see if it is in use before it is drawn.  So there is no
        /// need for caller to do so.
        /// </para>
        /// </remarks>
        private static void Draw(NavmeshTile tile
                                 , NavmeshQuery query, uint[] markPolys, int markPolyCount
                                 , int colorId)
        {
            NavmeshTileHeader header = tile.GetHeader();

            // Keep this check.  Less trouble for clients.
            if (header.polyCount < 1)
            {
                return;
            }

            DebugDraw.SimpleMaterial.SetPass(0);

            uint polyBase = tile.GetBasePolyRef();

            NavmeshPoly[] polys = new NavmeshPoly[header.polyCount];
            tile.GetPolys(polys);

            Vector3[] verts = new Vector3[header.vertCount];
            tile.GetVerts(verts);

            NavmeshDetailMesh[] meshes =
                new NavmeshDetailMesh[header.detailMeshCount];
            tile.GetDetailMeshes(meshes);

            byte[] detailTris = new byte[header.detailTriCount * 4];
            tile.GetDetailTris(detailTris);

            Vector3[] detailVerts = new Vector3[header.detailVertCount];
            tile.GetDetailVerts(detailVerts);

            GL.Begin(GL.TRIANGLES);
            for (int i = 0; i < header.polyCount; i++)
            {
                NavmeshPoly poly = polys[i];

                if (poly.Type == NavmeshPolyType.OffMeshConnection)
                {
                    continue;
                }

                NavmeshDetailMesh mesh = meshes[i];

                Color color = GetStandardColor(polyBase | (uint)i
                                               , poly.Area, colorId
                                               , query, markPolys, markPolyCount);

                GL.Color(color);

                for (int j = 0; j < mesh.triCount; j++)
                {
                    int pTri = (int)(mesh.triBase + j) * 4;

                    for (int k = 0; k < 3; k++)
                    {
                        // Note: iVert and pVert refer to different
                        // arrays.
                        int iVert = detailTris[pTri + k];
                        if (iVert < poly.vertCount)
                        {
                            // Get the vertex from the main vertices.
                            int pVert = poly.indices[iVert];
                            GL.Vertex(verts[pVert]);
                        }
                        else
                        {
                            // Get the vertex from the detail vertices.
                            int pVert = (int)
                                        (mesh.vertBase + iVert - poly.vertCount);
                            GL.Vertex(detailVerts[pVert]);
                        }
                    }
                }
            }
            GL.End();

            NavmeshLink[] links = new NavmeshLink[header.maxLinkCount];
            tile.GetLinks(links);

            GL.Begin(GL.LINES);

            DrawPolyBoundaries(header
                               , polys
                               , verts
                               , meshes
                               , detailTris
                               , detailVerts
                               , links
                               , new Color(0, 0.2f, 0.25f, 0.13f)
                               , true);

            DrawPolyBoundaries(header
                               , polys
                               , verts
                               , meshes
                               , detailTris
                               , detailVerts
                               , links
                               , new Color(0.65f, 0.2f, 0, 0.9f)
                               , false);

            if (header.connCount == 0)
            {
                GL.End();
                return;
            }

            NavmeshConnection[] conns = new NavmeshConnection[header.connCount];
            tile.GetConnections(conns);

            for (int i = 0; i < header.polyCount; i++)
            {
                NavmeshPoly poly = polys[i];

                if (poly.Type != NavmeshPolyType.OffMeshConnection)
                {
                    continue;
                }

                Color color = GetStandardColor(polyBase | (uint)i
                                               , poly.Area, colorId
                                               , query, markPolys, markPolyCount);

                // Note: Alpha of less than one doesn't look good because connections tend to
                // overlay a lot of geometry, resulting is off color transitions.
                color.a = 1;

                GL.Color(color);

                NavmeshConnection conn = conns[i - header.connBase];

                Vector3 va = verts[poly.indices[0]];
                Vector3 vb = verts[poly.indices[1]];

                // Check to see if start and end end-points have links.
                bool startSet = false;
                bool endSet   = false;
                for (uint k = poly.firstLink; k != Navmesh.NullLink; k = links[k].next)
                {
                    if (links[k].edge == 0)
                    {
                        startSet = true;
                    }
                    if (links[k].edge == 1)
                    {
                        endSet = true;
                    }
                }

                // For linked endpoints: Draw a line between on-mesh location and endpoint,
                // and draw circle at the endpoint.
                // For un-linked endpoints: Draw a small red x-marker.

                if (startSet)
                {
                    GL.Vertex(va);
                    GL.Vertex(conn.endpoints[0]);
                    DebugDraw.AppendCircle(conn.endpoints[0], conn.radius);
                }
                else
                {
                    GL.Color(Color.red);
                    DebugDraw.AppendXMarker(conn.endpoints[0], 0.1f);
                    GL.Color(color);
                }

                if (endSet)
                {
                    GL.Vertex(vb);
                    GL.Vertex(conn.endpoints[1]);
                    DebugDraw.AppendCircle(conn.endpoints[1], conn.radius);
                }
                else
                {
                    GL.Color(Color.red);
                    DebugDraw.AppendXMarker(conn.endpoints[1], 0.1f);
                    GL.Color(color);
                }

                DebugDraw.AppendArc(conn.endpoints[0], conn.endpoints[1]
                                    , 0.25f
                                    , conn.IsBiDirectional ? 0.6f : 0
                                    , 0.6f);
            }

            GL.End();
        }
Ejemplo n.º 29
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;
        }
Ejemplo n.º 30
0
        public void createScene()
        {
            // set background and some fog
            AdvancedMogreFramework.Singleton.m_pViewport.BackgroundColour = new ColourValue(1.0f, 1.0f, 0.8f);
            m_pSceneMgr.SetFog(FogMode.FOG_LINEAR, new ColourValue(1.0f, 1.0f, 0.8f), 0, 15, 100);

            // set shadow properties
            m_pSceneMgr.ShadowTechnique = ShadowTechnique.SHADOWTYPE_TEXTURE_MODULATIVE;
            m_pSceneMgr.ShadowColour    = new ColourValue(0.5f, 0.5f, 0.5f);
            m_pSceneMgr.SetShadowTextureSize(1024);
            m_pSceneMgr.ShadowTextureCount = 1;

            // disable default camera control so the character can do its own
            m_pCameraMan.setStyle(CameraStyle.CS_MANUAL);
            // use a small amount of ambient lighting
            m_pSceneMgr.AmbientLight = new ColourValue(0.3f, 0.3f, 0.3f);

            // add a bright light above the scene
            Light light = m_pSceneMgr.CreateLight();

            light.Type           = (Light.LightTypes.LT_POINT);
            light.Position       = new Mogre.Vector3(-10, 40, 20);
            light.SpecularColour = ColourValue.White;

            // create a floor mesh resource
            MeshManager.Singleton.CreatePlane("floor", ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME,
                                              new Plane(Mogre.Vector3.UNIT_Y, 0), 100, 100, 10, 10, true, 1, 10, 10, Mogre.Vector3.UNIT_Z);

            // create a floor entity, give it a material, and place it at the origin
            SceneProp floorSceneProp = new SceneProp(
                this,
                m_pSceneMgr,
                m_pSceneMgr.RootSceneNode,
                physicsScene,
                "Floor",
                "floor"
                );

            floorSceneProp.SetMaterialName("Examples/Rockwall");

            //Navmesh
            Navmesh      floorNavMesh = MeshToNavmesh.LoadNavmesh(floorSceneProp.Entity);
            NavmeshQuery query;
            NavmeshPoint retStartPoint;
            NavmeshPoint retEndPoint;

            org.critterai.Vector3 pointStart = new org.critterai.Vector3(0, 0, 0);
            org.critterai.Vector3 pointEnd   = new org.critterai.Vector3(0, 0, 0);
            org.critterai.Vector3 extents    = new org.critterai.Vector3(2, 2, 2);

            NavStatus status = NavmeshQuery.Create(floorNavMesh, 100, out query);

            Console.WriteLine("Status returned when NavmeshQuery was built: " + status);

            NavmeshQueryFilter filter = new NavmeshQueryFilter();

            filter.IncludeFlags = 1;

            status = query.GetNearestPoint(pointStart, extents, filter, out retStartPoint);
            Console.WriteLine("\nStatus of startPoint GetNearestPoint: " + status);
            status = query.GetNearestPoint(pointEnd, extents, filter, out retEndPoint);
            Console.WriteLine("\nStatus of endPoint GetNearestPoint: " + status);

            uint[] path = new uint[100];
            int    pathCount;

            status = query.FindPath(retStartPoint, retEndPoint, filter, path, out pathCount);
            Console.WriteLine("\nStatus of Find path: " + status);

            // create our character controller
            m_pChara = new SinbadCharacterController(this, physicsScene, m_pCamera, new Mogre.Vector3(0, 5, 0), 0);
            SinbadCharacterController bot1 = new SinbadCharacterController(this, physicsScene, m_pCamera, new Mogre.Vector3(-10, 5, 0), 1, false);
            SinbadCharacterController bot2 = new SinbadCharacterController(this, physicsScene, m_pCamera, new Mogre.Vector3(0, 5, -10), 2, false);
            SinbadCharacterController bot3 = new SinbadCharacterController(this, physicsScene, m_pCamera, new Mogre.Vector3(10, 5, 0), 3, false);

            agents.Add(m_pChara);
            agents.Add(bot1);
            agents.Add(bot2);
            agents.Add(bot3);

            AdvancedMogreFramework.Singleton.m_pTrayMgr.toggleAdvancedFrameStats();

            StringVector items = new StringVector();

            items.Insert(items.Count, "Help");
            ParamsPanel help = AdvancedMogreFramework.Singleton.m_pTrayMgr.createParamsPanel(TrayLocation.TL_TOPLEFT, "HelpMessage", 100, items);

            help.setParamValue("Help", "H / F1");
        }
Ejemplo n.º 31
0
        public NavManager CreateManager()
        {
            CheckCrowdAvoidanceSet();

            if (!(mNavmeshData && NavmeshData.HasNavmesh))
            {
                Debug.LogError("Aborted initialization. Navigation mesh not available.");
                return(null);
            }

            //Debug.Log("NavmeshData-------"+ NavmeshData);
            Navmesh navmesh = NavmeshData.GetNavmesh();

            if (navmesh == null)
            {
                NavStatus theStatus = Navmesh.Create(navMeshData, out navmesh);

                Debug.Log("Navmesh.Create ---->" + theStatus + "---->" + (int)(theStatus & NavStatus.Sucess));
                if (NavUtil.Failed(theStatus))
                {
                    Debug.LogError("NavUtil.Failed(Navmesh.Create(navMeshData, out navmesh) Fail!");
                }
                Debug.Log("--------------------\n" + navMeshData + "---" + navMeshData.Length + "\n-----------------\nNavmesh-------" + navmesh);
            }
            if (navmesh == null)
            {
                Debug.LogError(" navmesh is null");
                return(null);
            }
            NavmeshQuery query;
            NavStatus    status = NavmeshQuery.Create(navmesh, mMaxQueryNodes, out query);

            if ((status & NavStatus.Sucess) == 0)
            {
                Debug.LogError(" Aborted initialization. Failed query creation: " + status.ToString());
                return(null);
            }

            CrowdManager crowd = CrowdManager.Create(mMaxCrowdAgents, mMaxAgentRadius, navmesh);

            if (crowd == null)
            {
                Debug.LogError("Aborted initialization. Failed crowd creation.");
                return(null);
            }

            for (int i = 0; i < CrowdManager.MaxAvoidanceParams; i++)
            {
                crowd.SetAvoidanceConfig(i, CrowdAvoidanceConfig[i]);
            }
            NavGroup mGroup = new NavGroup(navmesh, query, crowd, crowd.QueryFilter, mExtents, false);

            int count = AgentGroupSettingManager.GetGroupCount();
            Dictionary <byte, NavAgentGroups> mAgentGroups = new Dictionary <byte, NavAgentGroups>(count);

            for (int i = 0; i < count; i++)
            {
                byte           groupId;
                NavAgentGroups group = AgentGroupSettingManager.CreateAgentGroup(i, mMaxPath, mMaxStraightPath, out groupId);
                group.angleAt         = mAngleAt;
                group.heightTolerance = mHeightTolerance;
                group.turnThreshold   = mTurnThreshold;

                mAgentGroups.Add(groupId, group);
            }
            return(NavManager.Create(mMaxAgents, mGroup, mAgentGroups));
        }