예제 #1
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;
            }
        }
예제 #2
0
        /// <summary>
        /// Adds an agent to the manager.
        /// </summary>
        /// <param name="position">
        /// The current position of the agent within the navigation mesh.
        /// </param>
        /// <param name="agentParams">The agent configuration.</param>
        /// <returns>
        /// A reference to the agent object created by the manager, or null on error.
        /// </returns>
        public CrowdAgent AddAgent(Vector3 position
                                   , CrowdAgentParams agentParams)
        {
            if (IsDisposed)
            {
                return(null);
            }

            IntPtr ptr = IntPtr.Zero;
            CrowdAgentCoreState initialState = new CrowdAgentCoreState();

            int index = CrowdManagerEx.dtcAddAgent(root
                                                   , ref position
                                                   , ref agentParams
                                                   , ref ptr
                                                   , ref initialState);

            if (index == -1)
            {
                return(null);
            }

            mAgents[index]     = new CrowdAgent(this, ptr, index);
            agentStates[index] = initialState;

            return(mAgents[index]);
        }
예제 #3
0
 /// <summary>
 /// Gets the velocity sample count.
 /// </summary>
 /// <returns>The velocity sample count.</returns>
 public int GetVelocitySampleCount()
 {
     if (IsDisposed)
     {
         return(-1);
     }
     return(CrowdManagerEx.dtcGetVelocitySampleCount(root));
 }
예제 #4
0
        /// <summary>
        /// Updates the steering and positions for all agents.
        /// </summary>
        /// <param name="deltaTime">The time in seconds to update the simulation.</param>
        public void Update(float deltaTime)
        {
            if (IsDisposed)
            {
                return;
            }

            CrowdManagerEx.dtcUpdate(root, deltaTime, agentStates);
        }
예제 #5
0
 /// <summary>
 /// Updates the configuration for an agent.
 /// </summary>
 /// <param name="config">The new agent configuration.</param>
 public void SetConfig(CrowdAgentParams config)
 {
     if (!IsDisposed)
     {
         CrowdManagerEx.dtcUpdateAgentParameters(mManager.root
                                                 , managerIndex
                                                 , ref config);
     }
 }
예제 #6
0
        /// <summary>
        /// The extents used by the manager when it performs queries against the navigation mesh.
        /// </summary>
        /// <remarks>
        /// <para>
        /// All agents and targets should remain within these distances of the navigation mesh
        /// surface.  For example, if the y-axis extent is 1.0, then the agent should remain
        /// between 1.0 above and 1.0 below the surface of the mesh.
        /// </para>
        /// <para>
        /// The extents remains constant over the life of the crowd manager.
        /// </para>
        /// </remarks>
        /// <returns>The extents.</returns>
        public Vector3 GetQueryExtents()
        {
            if (IsDisposed)
            {
                return(Vector3Util.Zero);
            }
            Vector3 result = Vector3Util.Zero;

            CrowdManagerEx.dtcGetQueryExtents(root, ref result);
            return(result);
        }
예제 #7
0
        /// <summary>
        /// Adjusts the position of an agent's target.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method is used to make small local adjustments to the target. (Such as happens
        /// when following a moving target.)  Use <see cref="RequestMoveTarget"/> when a new
        /// target is needed.
        /// </para>
        /// </remarks>
        /// <param name="position">The new target position.</param>
        /// <returns>True if the adjustment was successful.</returns>
        public bool AdjustMoveTarget(NavmeshPoint position)
        {
            if (IsDisposed)
            {
                return(false);
            }

            return(CrowdManagerEx.dtcAdjustMoveTarget(mManager.root
                                                      , managerIndex
                                                      , position));
        }
예제 #8
0
        /// <summary>
        /// Submits a new move request for the agent.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method is used when a new target is set.  Use <see cref="AdjustMoveTarget"/> when
        /// only small local adjustments are needed. (Such as happens when following a moving
        /// target.)
        /// </para>
        /// <para>
        /// The position will be constrained to the surface of the navigation mesh.
        /// </para>
        /// <para>
        /// The request will be processed during the next <see cref="CrowdManager.Update"/>.
        /// </para>
        /// </remarks>
        /// <param name="target">The target position.</param>
        /// <returns>True if the target was successfully set.</returns>
        public bool RequestMoveTarget(NavmeshPoint target)
        {
            if (IsDisposed)
            {
                return(false);
            }

            return(CrowdManagerEx.dtcRequestMoveTarget(mManager.root
                                                       , managerIndex
                                                       , target));
        }
예제 #9
0
        /// <summary>
        /// Sets the shared avoidance configuration for a specified index.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Multiple avoidance configurations can be set for the manager with agents assigned to
        /// different avoidance behaviors via the <see cref="CrowdAgentParams"/> object.
        /// </para>
        /// </remarks>
        /// <param name="index">
        /// The index. [Limits: 0 &lt;= value &lt; <see cref="MaxAvoidanceParams"/>].
        /// </param>
        /// <param name="config">The avoidance configuration.</param>
        /// <returns>True if the configuration is successfully set.</returns>
        public bool SetAvoidanceConfig(int index
                                       , CrowdAvoidanceParams config)
        {
            if (IsDisposed || index < 0 || index >= MaxAvoidanceParams)
            {
                return(false);
            }

            CrowdManagerEx.dtcSetObstacleAvoidanceParams(root, index, config);

            return(true);
        }
예제 #10
0
 /// <summary>
 /// Removes an agent from the manager.
 /// </summary>
 /// <remarks>
 /// <para>
 /// The <see cref="CrowdAgent"/> object will be immediately disposed. Continued use will
 /// result in undefined behavior.
 /// </para>
 /// </remarks>
 /// <param name="agent">The agent to remove.</param>
 public void RemoveAgent(CrowdAgent agent)
 {
     for (int i = 0; i < mAgents.Length; i++)
     {
         if (mAgents[i] == agent)
         {
             CrowdManagerEx.dtcRemoveAgent(root, agent.managerIndex);
             agent.Dispose();
             mAgents[i] = null;
             // Don't need to do anything about the core data array.
         }
     }
 }
예제 #11
0
        /// <summary>
        /// Gets the shared avoidance configuration for a specified index.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Getting a configuration for an index that has not been set will return a configuration
        /// in an undefined state.
        /// </para>
        /// </remarks>
        /// <param name="index">
        /// The index. [Limits: 0 &lt;= value &lt; <see cref="MaxAvoidanceParams"/>]
        /// </param>
        /// <returns>An avoidance configuration.</returns>
        public CrowdAvoidanceParams GetAvoidanceConfig(int index)
        {
            if (!IsDisposed && index >= 0 && index < MaxAvoidanceParams)
            {
                CrowdAvoidanceParams result = new CrowdAvoidanceParams();
                CrowdManagerEx.dtcGetObstacleAvoidanceParams(root
                                                             , index
                                                             , result);

                return(result);
            }
            return(null);
        }
예제 #12
0
        /// <summary>
        /// Creates a new crowd manager.
        /// </summary>
        /// <param name="maxAgents">
        /// The maximum number of agents that can be added to the manager.
        /// </param>
        /// <param name="maxAgentRadius">The maximum allowed agent radius.</param>
        /// <param name="navmesh">
        /// The navigation mesh to use for path planning and steering related queries.
        /// </param>
        /// <returns>A new crowd manager, or null on error.</returns>
        public static CrowdManager Create(int maxAgents, float maxAgentRadius, Navmesh navmesh)
        {
            if (navmesh == null || navmesh.IsDisposed)
            {
                return(null);
            }

            maxAgents      = Math.Max(1, maxAgents);
            maxAgentRadius = Math.Max(0, maxAgentRadius);

            IntPtr root =
                CrowdManagerEx.dtcDetourCrowdAlloc(maxAgents, maxAgentRadius, navmesh.root);

            if (root == IntPtr.Zero)
            {
                return(null);
            }

            return(new CrowdManager(root, navmesh, maxAgents, maxAgentRadius));
        }
예제 #13
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);
        }