/// <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; } }
private static NavStatus UnsafeCreate(byte[] serializedMesh , bool safeStorage , out Navmesh resultMesh) { if (serializedMesh == null || serializedMesh.Length == 0) { resultMesh = null; return(NavStatus.Failure | NavStatus.InvalidParam); } IntPtr root = IntPtr.Zero; NavStatus status = NavmeshEx.dtnmBuildDTNavMeshFromRaw(serializedMesh , serializedMesh.Length , safeStorage , ref root); if (NavUtil.Succeeded(status)) { resultMesh = new Navmesh(root); } else { resultMesh = null; } return(status); }
/// <summary> /// Creates a single-tile navigation mesh. /// </summary> /// <param name="buildData">The tile build data.</param> /// <param name="resultMesh">The result mesh.</param> /// <returns>The <see cref="NavStatus"/> flags for the operation. /// </returns> public static NavStatus Create(NavmeshTileBuildData buildData , out Navmesh resultMesh) { IntPtr navMesh = IntPtr.Zero; NavStatus status = NavmeshEx.dtnmBuildSingleTileMesh(buildData , ref navMesh); if (NavUtil.Succeeded(status)) { resultMesh = new Navmesh(navMesh); } else { resultMesh = null; } return(status); }
/// <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)); }
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); }
/// <summary> /// Creates an empty navigation mesh ready for tiles to be added. /// </summary> /// <remarks> /// This is the method used when creating new multi-tile meshes. /// Tiles are added using the <see cref="AddTile"/> method. /// </remarks> /// <param name="config">The mesh configuration.</param> /// <param name="resultMesh">The result mesh.</param> /// <returns>The <see cref="NavStatus"/> flags for the operation. /// </returns> public static NavStatus Create(NavmeshParams config , out Navmesh resultMesh) { if (config == null || config.maxTiles < 1) { resultMesh = null; return(NavStatus.Failure | NavStatus.InvalidParam); } IntPtr root = IntPtr.Zero; NavStatus status = NavmeshEx.dtnmInitTiledNavMesh(config, ref root); if (NavUtil.Succeeded(status)) { resultMesh = new Navmesh(root); } else { resultMesh = null; } return(status); }
private static NavStatus UnsafeCreate(byte[] serializedMesh , bool safeStorage , out Navmesh resultMesh) { if (serializedMesh == null || serializedMesh.Length == 0) { resultMesh = null; return NavStatus.Failure | NavStatus.InvalidParam; } IntPtr root = IntPtr.Zero; NavStatus status = NavmeshEx.dtnmBuildDTNavMeshFromRaw(serializedMesh , serializedMesh.Length , safeStorage , ref root); if (NavUtil.Succeeded(status)) resultMesh = new Navmesh(root); else resultMesh = null; return status; }
/// <summary> /// Creates a navigation mesh from data obtained from the <see cref="GetSerializedMesh"/> /// method. /// </summary> /// <param name="serializedMesh">The serialized mesh.</param> /// <param name="resultMesh">The result mesh.</param> /// <returns>The <see cref="NavStatus"/> flags for the operation. /// </returns> public static NavStatus Create(byte[] serializedMesh , out Navmesh resultMesh) { return UnsafeCreate(serializedMesh, true, out resultMesh); }
/// <summary> /// Creates a single-tile navigation mesh. /// </summary> /// <param name="buildData">The tile build data.</param> /// <param name="resultMesh">The result mesh.</param> /// <returns>The <see cref="NavStatus"/> flags for the operation. /// </returns> public static NavStatus Create(NavmeshTileBuildData buildData , out Navmesh resultMesh) { IntPtr navMesh = IntPtr.Zero; NavStatus status = NavmeshEx.dtnmBuildSingleTileMesh(buildData , ref navMesh); if (NavUtil.Succeeded(status)) resultMesh = new Navmesh(navMesh); else resultMesh = null; return status; }
internal NavmeshTile(Navmesh owner, IntPtr tile) { mOwner = owner; mTile = tile; }
/// <summary> /// Creates a new navigation mesh query based on the provided navigation mesh. /// </summary> /// <param name="navmesh">A navigation mesh to query against.</param> /// <param name="maximumNodes"> /// The maximum number of nodes allowed when performing A* and Dijkstra searches. /// </param> /// <param name="resultQuery">A navigation mesh query object.</param> /// <returns>The <see cref="NavStatus" /> flags for the build request.</returns> public static NavStatus Create(Navmesh navmesh , int maximumNodes , out NavmeshQuery resultQuery) { IntPtr query = IntPtr.Zero; NavStatus status = NavmeshQueryEx.dtnqBuildDTNavQuery( navmesh.root , maximumNodes , ref query); if (NavUtil.Succeeded(status)) resultQuery = new NavmeshQuery(query, false, AllocType.External); else resultQuery = null; return status; }
/// <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; } }
/// <summary> /// Creates a navigation mesh from data obtained from the <see cref="GetSerializedMesh"/> /// method. /// </summary> /// <param name="serializedMesh">The serialized mesh.</param> /// <param name="resultMesh">The result mesh.</param> /// <returns>The <see cref="NavStatus"/> flags for the operation. /// </returns> public static NavStatus Create(byte[] serializedMesh , out Navmesh resultMesh) { return(UnsafeCreate(serializedMesh, true, out resultMesh)); }
/// <summary> /// Extracts the tile data from a serialized navigation mesh. /// </summary> /// <remarks> /// <para> /// Tile data is normally preserved by serializing /// the the content of the <see cref="NavmeshTileData"/> objects used to /// create the navigation mesh. That is the most efficient method /// and should be used whenever possible. /// </para> /// <para> /// This method can be used to extract the tile data when /// the original data is not available. It should only be used as /// a backup to the normal method since this method is not efficient. /// </para> /// <para> /// Always check the header polygon count /// of the resulting <see cref="NavmeshTileExtract"/> objects before use since some tiles /// in the navigation mesh may be empty. The <see cref="NavmeshTileExtract.data"/> /// field will be null for empty tiles. /// </para> /// </remarks> /// <param name="serializedMesh">A valid serialized navigation mesh.</param> /// <param name="tileData"> /// The extracted tile data. [Length: <see cref="Navmesh.GetMaxTiles()"/>] /// </param> /// <param name="config">The navigation mesh's configuration.</param> /// <returns>The <see cref="NavStatus"/> flags for the operation.</returns> public static NavStatus ExtractTileData(byte[] serializedMesh , out NavmeshTileExtract[] tileData , out NavmeshParams config) { /* * Design notes: * * Normally, the only way to get tile data out of a navigation mesh * is when the tile data is NOT owned by the mesh. This is not * permitted for normal mesh objects, which is why the RemoveTile() method * never returns the tile data. * * The most efficient way to extract the data is to get it directly * from the serialized data. But that would be a code maintenance issue. * (Duplicating the mesh creation process.) So I'm using this rather * convoluted method instead. * */ if (serializedMesh == null) { tileData = null; config = null; return(NavStatus.Failure | NavStatus.InvalidParam); } Navmesh mesh; NavStatus status = Navmesh.UnsafeCreate(serializedMesh, false, out mesh); if ((status & NavStatus.Failure) != 0) { tileData = null; config = null; return(status); } config = mesh.GetConfig(); int count = mesh.GetMaxTiles(); tileData = new NavmeshTileExtract[count]; if (count == 0) { return(NavStatus.Sucess); } for (int i = 0; i < count; i++) { NavmeshTile tile = mesh.GetTile(i); tileData[i].header = tile.GetHeader(); if (tileData[i].header.polyCount == 0) { // Tile not in use. continue; } tileData[i].tileRef = tile.GetTileRef(); IntPtr tdata = new IntPtr(); int tsize = 0; NavmeshEx.dtnmRemoveTile(mesh.root, tileData[i].tileRef, ref tdata, ref tsize); tileData[i].data = UtilEx.ExtractArrayByte(tdata, tsize); NavmeshEx.dtnmFreeBytes(ref tdata); } return(NavStatus.Sucess); }
/// <summary> /// Creates an empty navigation mesh ready for tiles to be added. /// </summary> /// <remarks> /// This is the method used when creating new multi-tile meshes. /// Tiles are added using the <see cref="AddTile"/> method. /// </remarks> /// <param name="config">The mesh configuration.</param> /// <param name="resultMesh">The result mesh.</param> /// <returns>The <see cref="NavStatus"/> flags for the operation. /// </returns> public static NavStatus Create(NavmeshParams config , out Navmesh resultMesh) { if (config == null || config.maxTiles < 1) { resultMesh = null; return NavStatus.Failure | NavStatus.InvalidParam; } IntPtr root = IntPtr.Zero; NavStatus status = NavmeshEx.dtnmInitTiledNavMesh(config, ref root); if (NavUtil.Succeeded(status)) resultMesh = new Navmesh(root); else resultMesh = null; return status; }
/// <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); }