Exemple #1
0
    /// <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);
    }
Exemple #2
0
    /// <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);
    }
Exemple #3
0
        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);
        }
Exemple #4
0
    /// <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);
    }
Exemple #5
0
    /// <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);
    }
Exemple #6
0
        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);
            }
        }
Exemple #7
0
    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);
    }
Exemple #8
0
    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);
            }
        }
Exemple #10
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));
        }