/// <summary> /// Loads a single-tile navigation mesh from the provided data. /// </summary> /// <param name="buildData">The tile build data.</param> /// <param name="buildConfig">The build information. (Optional)</param> /// <returns>The <see cref="NavStatus"/> flags for the operation.</returns> public NavStatus Load(NavmeshTileBuildData buildData, NavmeshBuildInfo buildConfig) { if (buildData == null || buildData.IsDisposed) { return(NavStatus.Failure | NavStatus.InvalidParam); } Navmesh navmesh; NavStatus status = Navmesh.Create(buildData, out navmesh); if ((status & NavStatus.Sucess) == 0) { return(status); } mDataPack = navmesh.GetSerializedMesh(); if (mDataPack == null) { return(NavStatus.Failure); } mBuildInfo = buildConfig; mVersion++; return(NavStatus.Sucess); }
/// <summary> /// Load a navigation mesh from data created from the <see cref="Navmesh.GetSerializedMesh"/> /// method. /// </summary> /// <param name="serializedMesh">The serialized mesh.</param> /// <param name="buildConfig">The build information. (Optional)</param> /// <returns>The <see cref="NavStatus"/> flags for the operation.</returns> public NavStatus Load(byte[] serializedMesh, NavmeshBuildInfo buildConfig) { if (serializedMesh == null) { return(NavStatus.Failure | NavStatus.InvalidParam); } // This roundabout method is used for validation. Navmesh navmesh; NavStatus status = Navmesh.Create(serializedMesh, out navmesh); if ((status & NavStatus.Sucess) == 0) { return(status); } mDataPack = navmesh.GetSerializedMesh(); if (mDataPack == null) { return(NavStatus.Failure); } mBuildInfo = buildConfig; mVersion++; return(NavStatus.Sucess); }
public static Pathfinder Create(string filePath) { BinaryFormatter formatter = new BinaryFormatter(); FileStream stream = null; if (!File.Exists(filePath)) { return(null); } try { stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); NavStatus status = Navmesh.Create((byte[])formatter.Deserialize(stream), out Navmesh navMesh); if (status == NavStatus.Sucess) { return(new Pathfinder(navMesh)); } } finally { if (stream != null) { stream.Close(); } } return(null); }
/// <summary> /// Creates a new <see cref="Navmesh"/> object from the mesh data /// </summary> /// <returns>A new <see cref="Navmesh"/> object. Or null if the mesh is not available.</returns> public Navmesh GetNavmesh() { if (!HasNavmesh) { return(null); } Navmesh result; if (NavUtil.Failed(Navmesh.Create(mDataPack, out result))) { return(null); } return(result); }
/// <summary> /// Loads a navigation mesh. /// </summary> /// <param name="config">The mesh configuration.</param> /// <param name="tiles">The tiles to add to the mesh.</param> /// <param name="buildConfig">The build information. (Optional)</param> /// <returns>The <see cref="NavStatus"/> flags for the operation.</returns> public NavStatus Load(NavmeshParams config , NavmeshTileData[] tiles , NavmeshBuildInfo buildConfig) { if (config == null || tiles == null || tiles.Length > config.maxTiles) { return(NavStatus.Failure | NavStatus.InvalidParam); } Navmesh navmesh; NavStatus status = Navmesh.Create(config, out navmesh); if ((status & NavStatus.Sucess) == 0) { return(status); } foreach (NavmeshTileData tile in tiles) { if (tile == null) { continue; } uint trash; status = navmesh.AddTile(tile, Navmesh.NullTile, out trash); if ((status & NavStatus.Sucess) == 0) { return(status | NavStatus.InvalidParam); } } mDataPack = navmesh.GetSerializedMesh(); if (mDataPack == null) { return(NavStatus.Failure); } mBuildInfo = buildConfig; mVersion++; return(NavStatus.Sucess); }
private bool LoadMapFromBuffer(byte[] buffer) { Clear(); if (buffer == null || buffer.Length <= 0) { return(false); } try { var status = Navmesh.Create(buffer, out m_NavMesh); var ret = NavUtil.Succeeded(status) && m_NavMesh != null; if (!ret) { Clear(); } return(ret); } catch { return(false); } }
private NavStatus loadMeshData(string fileName) { Debug.Log("loadMesshDataBegin"); byte[] serializedMesh = readFileByte(fileName); this.fileName = fileName; if (serializedMesh == null) { Debug.Log("serializedMesh == null"); return(NavStatus.Failure | NavStatus.InvalidParam); } // This roundabout method is used for validation. NavStatus status = Navmesh.Create(serializedMesh, out navmesh); if ((status & NavStatus.Sucess) == 0) { Debug.Log("Navmesh.Create Failed"); Debug.Log(status.ToString()); return(status); } //byte[] mDataPack = navmesh.GetSerializedMesh(); //转一遍测试一下 //if (mDataPack == null) //{ // Debug.Log("navmesh.GetSerializedMesh() Failed"); // Debug.Log(mDataPack.ToString()); // return NavStatus.Failure; //} //mBuildInfo = buildConfig; = null; Debug.Log("loadMesshDataSuccess"); return(NavStatus.Sucess); }
private static Navmesh GenerateNavmesh() { #region Generate Neighboring polygon data //Then generate neighboring polygon data, by parsing the face list MyVector3 <bool> sharedVertex; //For the current face, what vertices are shared with the other face? int sharedVertices; //if goes to 2, edge is shared for (ushort q = 0; q < faces.Count; q++) { //Index of face and neighborPoly refer to the same polygon. neighborPolys.Add(new MyVector3 <ushort>()); neighborPolys[q].x = Navmesh.NullIndex; neighborPolys[q].y = Navmesh.NullIndex; neighborPolys[q].z = Navmesh.NullIndex; //Compare this face with every other face for (ushort w = 0; w < faces.Count; w++) { if (w != q) { sharedVertices = 0; sharedVertex = new MyVector3 <bool>(); //Go from left to right in the face MyVector3 for (int j = 0; j <= 2; j++) { //And compare each index with every other index for (int k = 0; k <= 2; k++) { if (faces[q][j] == faces[w][k]) { //If we find a matching index, update stuff (only for the current face, dont bother with other face, can optimise but will be confusing) sharedVertices++; sharedVertex[j] = true; //could break out of the for loop now, as face will not list the same index twice } } } if (sharedVertices > 2) { ReportError("error: more than 2 vertices shared between polys " + q + " and " + w); } //Check if these faces are sharing an edge if (sharedVertices == 2) { //get the Leftmost Right-To-Left Pair in the neighborPolys MyVector3 //options are: edge 0-1, 1-2, and 2-0, respectively indexing neighboringPolys. (i.e. if index 1 of neighboring polys is 45, that means that the current polygon and polygon 45 share the edge face[1] <-> face[2] if (sharedVertex[0] == true) { if (sharedVertex[1] == true) { neighborPolys[q][0] = w; //I.e. tell this face's MyVector3 of neighboring polygons that the edge made up by vertices at 0 and 1 is shared between polygon q and w } else { neighborPolys[q][2] = w; } } else { neighborPolys[q][1] = w; } } } //End iterating through other faces } } //End iterating through each face #endregion //Now, Load these into Critter AI and create a navmesh navData = new NavmeshTileBuildData(maxPolyVerts, maxPolys, maxVertsPerPoly, 0, 0, 0); #region LoadBase //Get the min and max bounds from the vertex positions float lowest; float highest; //Find the bounds of the mesh. iterate through the x, y and z axes for (int axis = 0; axis <= 2; axis++) { lowest = UPPER_LIMIT; //set to inital values that they do not reach highest = LOWER_LIMIT; //iterate through every vertex to find highest and lowest value of this axis for (int i = 0; i < vertices.Count; i++) { if (vertices[i][axis] < lowest) { lowest = vertices[i][axis]; } if (vertices[i][axis] > highest) { highest = vertices[i][axis]; } } if (axis == 0) //x { boundsMin.x = lowest; boundsMax.x = highest; } else if (axis == 1) { boundsMin.y = lowest; boundsMax.y = highest; } else if (axis == 2) { boundsMin.z = lowest; boundsMax.z = highest; } } bool sucess; sucess = navData.LoadBase(tileX, tileZ, tileLayer, tileUserId, boundsMin, boundsMax, xzCellSize, yCellSize, walkableHeight, walkableRadius, walkableStep, bvTreeEnabled); if (!sucess) { ReportError("Error, LoadBase returned false"); } #endregion #region LoadPolys vertCount = vertices.Count; polyCount = faces.Count; //Convert vertices from world space to grid space polyVerts = new ushort[vertCount * 3]; for (int i = 0; i < vertCount; i++) { polyVerts[3 * i + 0] = (ushort)Math.Round((vertices[i].x - boundsMin.x) / xzCellSize); polyVerts[3 * i + 1] = (ushort)Math.Round((vertices[i].y - boundsMin.y) / yCellSize); polyVerts[3 * i + 2] = (ushort)Math.Round((vertices[i].z - boundsMin.z) / xzCellSize); } //build polys array (http://www.critterai.org/projects/cainav/doc/html/B8C2F0F4.htm) polys = new ushort[6 * polyCount]; int ind = 0; int faceNo = 0; while (faceNo < polyCount) { polys[ind + 0] = faces[faceNo].x; polys[ind + 1] = faces[faceNo].y; polys[ind + 2] = faces[faceNo].z; polys[ind + 3] = neighborPolys[faceNo].x; polys[ind + 4] = neighborPolys[faceNo].y; polys[ind + 5] = neighborPolys[faceNo].z; ind += 6; faceNo++; } //Fill polyflags array with default flags polyFlags = new ushort[polyCount]; for (int i = 0; i < polyCount; i++) { polyFlags[i] = 1; //custom user flag } //Fill polyAreas array polyAreas = new byte[polyCount]; for (int i = 0; i < polyCount; i++) { polyAreas[i] = 1; } sucess = navData.LoadPolys(polyVerts, vertCount, polys, polyFlags, polyAreas, polyCount); if (!sucess) { ReportError("Error, LoadPolys returned false"); } #endregion //Build the Navmesh using the navData NavStatus status = Navmesh.Create(navData, out navmesh); if (status != NavStatus.Sucess) { ReportError("Navmesh build status was " + status.ToString()); } return(navmesh); }
private void HandleWorkingNavmesh(TileSelection selection) { NavmeshBuild build = selection.Build; TileBuildData tdata = build.BuildData; if (mDebugObject == null) { Navmesh navmesh = null; if (tdata.BakeableCount() == 0) { // Nothing to display. return; } bool success = true; TileSetDefinition tdef = build.TileSetDefinition; NavmeshParams nconfig; NavmeshTileData[] tiles; if (tdef == null) { tiles = new NavmeshTileData[1] { tdata.GetTileData(0, 0) }; nconfig = NavUtil.DeriveConfig(tiles[0]); } else { TileZone zone; if (selection.HasSelection) { zone = selection.Zone; } else { zone = new TileZone(0, 0, tdef.Width - 1, tdef.Depth - 1); } success = tdata.GetMeshBuildData(tdef.BoundsMin.ToUnityVector3(), tdef.TileWorldSize, zone , out nconfig, out tiles); } NavStatus status = NavStatus.Sucess; if (success) { status = Navmesh.Create(nconfig, out navmesh); if ((status & NavStatus.Failure) == 0) { foreach (NavmeshTileData tile in tiles) { uint trash; status = navmesh.AddTile(tile, Navmesh.NullTile, out trash); if ((status & NavStatus.Sucess) == 0) { navmesh = null; break; } } } } if ((status & NavStatus.Sucess) == 0) { Show = MeshDebugOption.None; // Use property. Debug.LogError("Mesh Debug View: Error creating working navigation mesh: " + status + ". Disabled display.", build); } else { mDebugObject = navmesh; } } if (mDebugObject != null) { Navmesh nm = ( Navmesh )mDebugObject; NavDebug.Draw(nm, NavmeshSceneDraw.Instance.ColorByArea); } }
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)); }