コード例 #1
0
    public void BuildTile(int x, int y)
    {
        RecastVertex bmin     = Geometry.MinBounds;
        RecastVertex bmax     = Geometry.MaxBounds;
        float        tcs      = Config.TileSize * Config.CellSize;
        RecastVertex tileBMin = new RecastVertex();
        RecastVertex tileBMax = new RecastVertex();

        tileBMin.X = bmin.X + x * tcs;
        tileBMin.Y = bmin.Y;
        tileBMin.Z = bmin.Z + y * tcs;

        tileBMax.X = bmin.X + (x + 1) * tcs;
        tileBMax.Y = bmax.Y;
        tileBMax.Z = bmin.Z + (y + 1) * tcs;

        var builder = BuildTileMesh(x, y, tileBMin, tileBMax);

        // remove/add new tile?
        if (builder != null)
        {
            LunaNav.NavMeshBuilder outBuilder;
            // nav mesh remove tile
            NavMesh.RemoveTile(NavMesh.GetTileRefAt(x, y, 0), out outBuilder);
            // nav mesh add tile
            long result = 0;
            NavMesh.AddTile(builder, NavMesh.TileFreeData, 0, ref result);
        }
    }
コード例 #2
0
    private void Xloop(int y, int x, float tcs, RecastVertex bmin, RecastVertex bmax)
    {
        RecastVertex tileBMin = new RecastVertex();
        RecastVertex tileBMax = new RecastVertex();

        tileBMin.X = bmin.X + x * tcs;
        tileBMin.Y = bmin.Y;
        tileBMin.Z = bmin.Z + y * tcs;

        tileBMax.X = bmin.X + (x + 1) * tcs;
        tileBMax.Y = bmax.Y;
        tileBMax.Z = bmin.Z + (y + 1) * tcs;
        bool canceled = EditorUtility.DisplayCancelableProgressBar("Generating...",
                                                                   "Generating Tile " + Progress + " of " + Total,
                                                                   Progress / (float)Total);

        if (canceled)
        {
            //tokenSource.Cancel();
        }
        //var t = Task.Factory.StartNew(() => BuildTile(x, y, tileBMin, tileBMax), tokenSource.Token, TaskCreationOptions.LongRunning, scheduler);
        //tasks.Add(t);

        BuildTile(x, y, tileBMin, tileBMax);
    }
コード例 #3
0
    public void BuildTileSizeData()
    {
        RecastVertex bmin = _geom.MinBounds;
        RecastVertex bmax = _geom.MaxBounds;

        int gw = 0, gh = 0;

        CalcGridSize(bmin, bmax, _config.CellSize, out gw, out gh);

        int ts = TileSize;
        int tw = (gw + ts - 1) / ts;
        int th = (gh + ts - 1) / ts;

        TileWidth  = tw;
        TileHeight = th;

        int tileBits = Math.Min(ilog2(nextPow2(th * tw)), 14);

        if (tileBits > 14)
        {
            tileBits = 14;
        }

        int polyBits = 22 - tileBits;

        MaxTiles        = 1 << tileBits;
        MaxPolysPerTile = 1 << polyBits;
    }
コード例 #4
0
    /// <summary>
    /// Builds the entire NavMesh from the Data gathered by BuildGeometry through the Detail Mesh
    /// Then it creates a GameObject that has the RecastNavMesh.
    /// </summary>
    /// <returns></returns>
    public long BuildAllTiles(Config config, Geometry geom, int tileWidth, int tileHeight, int maxPolysPerTile, int maxTiles)
    {
        NavMesh = new Detour.NavMesh();
        NavMeshParams param = new NavMeshParams()
        {
            Orig       = geom.MinBounds.ToArray(),
            MaxPolys   = maxPolysPerTile,
            MaxTiles   = maxTiles,
            TileWidth  = config.TileSize * config.CellSize,
            TileHeight = config.TileSize * config.CellSize
        };

        NavMesh.Init(param);
        TileWidth  = tileWidth;
        TileHeight = tileHeight;
        Config     = config;
        Geometry   = geom;
        Progress   = 0;
        IsBuilding = true;
        Stopwatch timer = new Stopwatch();

        timer.Start();
        RecastVertex bmin = geom.MinBounds;
        RecastVertex bmax = geom.MaxBounds;
        float        tcs  = config.TileSize * config.CellSize;

        Total = TileWidth * TileHeight;
        bool canceled = false;

        for (int y = 0; y < TileHeight; y++)
        {
            YLoop(y, tcs, bmin, bmax);
        }

        if (!canceled)
        {
            while (Progress != Total)
            {
                canceled = EditorUtility.DisplayCancelableProgressBar("Generating...",
                                                                      "Generating Tile " + Progress + " of " + Total,
                                                                      Progress / (float)Total);
                if (canceled)
                {
                    tokenSource.Cancel();
                    break;
                }
            }
        }

        Task.WaitAll(tasks.ToArray());

        timer.Stop();

        EditorUtility.ClearProgressBar();
        IsBuilding = false;
        BuildGeometry();
        return(timer.ElapsedMilliseconds);
    }
コード例 #5
0
 private void CalcGridSize(RecastVertex bmin, RecastVertex bmax, float cellSize, out int w, out int h)
 {
     if (bmin != null && bmax != null)
     {
         w = (int)((bmax.X - bmin.X) / cellSize + 0.5f);
         h = (int)((bmax.Z - bmin.Z) / cellSize + 0.5f);
     }
     else
     {
         w = 0;
         h = 0;
     }
 }
コード例 #6
0
    private void YLoop(int y, float tcs, RecastVertex bmin, RecastVertex bmax)
    {
        bool canceled = false;

        for (int x = 0; x < TileWidth; x++)
        {
            canceled = EditorUtility.DisplayCancelableProgressBar("Generating...",
                                                                  "Generating Tile " + Progress + " of " + Total,
                                                                  Progress / (float)Total);
            if (canceled)
            {
                //tokenSource.Cancel();
                break;
            }
            Xloop(y, x, tcs, bmin, bmax);
        }
    }
コード例 #7
0
    public void RebuildTiles()
    {
        Progress   = 0;
        IsBuilding = true;
        RecastVertex bmin     = Geometry.MinBounds;
        RecastVertex bmax     = Geometry.MaxBounds;
        RecastVertex tileBMin = new RecastVertex();
        RecastVertex tileBMax = new RecastVertex();
        float        tcs      = Config.TileSize * Config.CellSize;

        Total = TileWidth * TileHeight;
        for (int y = 0; y < TileHeight; y++)
        {
            for (int x = 0; x < TileWidth; x++)
            {
                Progress   = y * TileWidth + x;
                tileBMin.X = bmin.X + x * tcs;
                tileBMin.Y = bmin.Y;
                tileBMin.Z = bmin.Z + y * tcs;

                tileBMax.X = bmin.X + (x + 1) * tcs;
                tileBMax.Y = bmax.Y;
                tileBMax.Z = bmin.Z + (y + 1) * tcs;

                EditorUtility.DisplayProgressBar("Generating...", "Generating Tile " + Progress + " of " + Total, Progress / (float)Total);
                var builder = BuildTileMesh(x, y, tileBMin, tileBMax);

                // remove/add new tile?
                if (builder != null)
                {
                    LunaNav.NavMeshBuilder outBuilder;
                    // nav mesh remove tile
                    NavMesh.RemoveTile(NavMesh.GetTileRefAt(x, y, 0), out outBuilder);
                    // nav mesh add tile
                    long result = 0;
                    NavMesh.AddTile(builder, NavMesh.TileFreeData, 0, ref result);
                }
            }
        }

        EditorUtility.ClearProgressBar();
        IsBuilding = false;
        BuildGeometry();
    }
コード例 #8
0
    public void BuildTile(int x, int y, RecastVertex tileBMin, RecastVertex tileBMax)
    {
        var builder = BuildTileMesh(x, y, tileBMin, tileBMax);

        // remove/add new tile?
        if (builder != null)
        {
            lock (this)
            {
                LunaNav.NavMeshBuilder outBuilder;
                // nav mesh remove tile
                NavMesh.RemoveTile(NavMesh.GetTileRefAt(x, y, 0), out outBuilder);
                // nav mesh add tile
                long result = 0;
                NavMesh.AddTile(builder, NavMesh.TileFreeData, 0, ref result);
            }
        }
        Progress++;
    }
コード例 #9
0
ファイル: AtavismNavMesh.cs プロジェクト: zukeru/ageofasura
    public void BuildTile(int x, int y, RecastVertex tileBMin, RecastVertex tileBMax)
    {
        var builder = BuildTileMesh(x, y, tileBMin, tileBMax);

            // remove/add new tile?
            if (builder != null)
            {
                lock (this)
                {
                    Detour.AtavismNavTile outBuilder;
                    // nav mesh remove tile
                    NavMesh.RemoveTile(NavMesh.GetTileRefAt(x, y, 0), out outBuilder);
                    // nav mesh add tile
                    long result = 0;
                    NavMesh.AddTile(builder, NavMesh.TileFreeData, 0, ref result);
                }
            }
            Progress++;
    }
コード例 #10
0
ファイル: ServerNavMesh.cs プロジェクト: zukeru/ageofasura
 private static void CalcGridSize(RecastVertex bmin, RecastVertex bmax, float cellSize, out int w, out int h)
 {
     if (bmin != null && bmax != null)
     {
         w = (int) ((bmax.X - bmin.X)/cellSize + 0.5f);
         h = (int) ((bmax.Z - bmin.Z)/cellSize + 0.5f);
     }
     else
     {
         w = 0;
         h = 0;
     }
 }
コード例 #11
0
    /// <summary>
    /// This takes the current geometry and builds the data to go into Recast
    /// It needs to be updated to take into account scale, position, and rotation
    /// It needs to be updated to look for specific tags
    /// </summary>
    /// <param name="geom"></param>
    private void BuildGeometry(Config config, Geometry geom)
    {
        for (int i = 0; i < UnityEditorInternal.InternalEditorUtility.tags.Length; i++)
        {
            if ((Tags & (1 << i)) != 0)
            {
                foreach (var gameObject in GameObject.FindGameObjectsWithTag(UnityEditorInternal.InternalEditorUtility.tags[i]))
                {
                    foreach (var terrainObj in gameObject.GetComponentsInChildren <Terrain>())
                    {
                        var terrain   = terrainObj.terrainData;
                        var w         = terrain.heightmapWidth;
                        var h         = terrain.heightmapHeight;
                        var meshScale = terrain.size;
                        var tRes      = 1;
                        meshScale = new Vector3(meshScale.x / (w - 1) * tRes, meshScale.y, meshScale.z / (h - 1) * tRes);
                        var tData = terrain.GetHeights(0, 0, w, h);

                        w = (w - 1) / tRes + 1;
                        h = (h - 1) / tRes + 1;
                        var tVertices = new Vector3[w * h];
                        var tPolys    = new int[(w - 1) * (h - 1) * 6];

                        // Build vertices and UVs
                        for (int y = 0; y < h; y++)
                        {
                            for (int x = 0; x < w; x++)
                            {
                                tVertices[y * w + x] = Vector3.Scale(meshScale, new Vector3(x, tData[y * tRes, x * tRes], y)) + terrainObj.transform.position;
                            }
                        }

                        var index = 0;
                        // Build triangle indices: 3 indices into vertex array for each triangle
                        for (int y = 0; y < h - 1; y++)
                        {
                            for (int x = 0; x < w - 1; x++)
                            {
                                // For each grid cell output two triangles
                                tPolys[index++] = (y * w) + x;
                                tPolys[index++] = ((y + 1) * w) + x;
                                tPolys[index++] = (y * w) + x + 1;

                                tPolys[index++] = ((y + 1) * w) + x;
                                tPolys[index++] = ((y + 1) * w) + x + 1;
                                tPolys[index++] = (y * w) + x + 1;
                            }
                        }
                        int subTotalVerts = geom.NumVertexes;
                        foreach (var tVertex in tVertices)
                        {
                            geom.Vertexes.Add(new RecastVertex(tVertex.x, tVertex.y, tVertex.z));
                            geom.NumVertexes++;
                        }
                        for (int j = 0; j < tPolys.Length; j += 3)
                        {
                            geom.Triangles.Add(tPolys[j] + subTotalVerts);
                            geom.Triangles.Add(tPolys[j + 1] + subTotalVerts);
                            geom.Triangles.Add(tPolys[j + 2] + subTotalVerts);
                            geom.NumTriangles++;
                        }
                    }
                    foreach (var componentsInChild in gameObject.GetComponentsInChildren <MeshFilter>())
                    {
                        int subTotalVerts = geom.NumVertexes;
                        foreach (Vector3 vector3 in componentsInChild.sharedMesh.vertices)
                        {
                            Vector3 vec = gameObject.transform.TransformPoint(vector3);
                            geom.Vertexes.Add(new RecastVertex(vec.x, vec.y, vec.z));
                            geom.NumVertexes++;
                        }
                        for (int j = 0; j < componentsInChild.sharedMesh.triangles.Length; j += 3)
                        {
                            geom.Triangles.Add(componentsInChild.sharedMesh.triangles[j] + subTotalVerts);
                            geom.Triangles.Add(componentsInChild.sharedMesh.triangles[j + 1] + subTotalVerts);
                            geom.Triangles.Add(componentsInChild.sharedMesh.triangles[j + 2] + subTotalVerts);
                            geom.NumTriangles++;
                        }
                    }
                    foreach (var offMeshConnector in gameObject.GetComponentsInChildren <OffMeshConnector>())
                    {
                        RecastVertex start = new RecastVertex(offMeshConnector.StartPosition.x, offMeshConnector.StartPosition.y, offMeshConnector.StartPosition.z);
                        RecastVertex end   = new RecastVertex(offMeshConnector.EndPosition.x, offMeshConnector.EndPosition.y, offMeshConnector.EndPosition.z);
                        geom.AddOffMeshConnection(start, end, offMeshConnector.Radius, offMeshConnector.Bidirectional, 5, 8);
                    }
                }
            }
        }
        Verts = geom.NumVertexes;
        Tris  = geom.NumTriangles;

        if (Verts != 0)
        {
            geom.CalculateBounds();
            config.CalculateGridSize(geom);
            geom.CreateChunkyTriMesh();
        }
    }
コード例 #12
0
ファイル: ServerNavMesh.cs プロジェクト: zukeru/ageofasura
    /// <summary>
    /// This takes the current geometry and builds the data to go into Recast
    /// It needs to be updated to take into account scale, position, and rotation
    /// It needs to be updated to look for specific tags
    /// </summary>
    /// <param name="geom"></param>
    private static void BuildGeometry(NavMeshSettings settings, Config config, Geometry geom)
    {
        for (int i = 0; i < UnityEditorInternal.InternalEditorUtility.tags.Length; i++)
        {
            if ((settings.Tags & (1 << i)) != 0)
            {
                foreach (var gameObject in GameObject.FindGameObjectsWithTag(UnityEditorInternal.InternalEditorUtility.tags[i]))
                {
                    foreach (var terrainObj in gameObject.GetComponentsInChildren<Terrain>())
                    {
                        var terrain = terrainObj.terrainData;
                        var w = terrain.heightmapWidth;
                        var h = terrain.heightmapHeight;
                        var meshScale = terrain.size;
                        var tRes = 1;
                        meshScale = new Vector3(meshScale.x / (w - 1) * tRes, meshScale.y, meshScale.z / (h - 1) * tRes);
                        var tData = terrain.GetHeights(0, 0, w, h);

                        w = (w - 1) / tRes + 1;
                        h = (h - 1) / tRes + 1;
                        var tVertices = new Vector3[w * h];
                        var tPolys = new int[(w - 1) * (h - 1) * 6];

                        // Build vertices and UVs
                        for (int y = 0; y < h; y++)
                        {
                            for (int x = 0; x < w; x++)
                            {
                                tVertices[y * w + x] = Vector3.Scale(meshScale, new Vector3(x, tData[y * tRes, x * tRes], y)) + terrainObj.transform.position;
                            }
                        }

                        var index = 0;
                        // Build triangle indices: 3 indices into vertex array for each triangle
                        for (int y = 0; y < h - 1; y++)
                        {
                            for (int x = 0; x < w - 1; x++)
                            {
                                // For each grid cell output two triangles
                                tPolys[index++] = (y * w) + x;
                                tPolys[index++] = ((y + 1) * w) + x;
                                tPolys[index++] = (y * w) + x + 1;

                                tPolys[index++] = ((y + 1) * w) + x;
                                tPolys[index++] = ((y + 1) * w) + x + 1;
                                tPolys[index++] = (y * w) + x + 1;
                            }
                        }
                        int subTotalVerts = geom.NumVertexes;
                        foreach (var tVertex in tVertices)
                        {
                            geom.Vertexes.Add(new RecastVertex(tVertex.x, tVertex.y, tVertex.z));
                            geom.NumVertexes++;
                        }
                        for (int j = 0; j < tPolys.Length; j += 3)
                        {
                            geom.Triangles.Add(tPolys[j] + subTotalVerts);
                            geom.Triangles.Add(tPolys[j + 1] + subTotalVerts);
                            geom.Triangles.Add(tPolys[j + 2] + subTotalVerts);
                            geom.NumTriangles++;
                        }
                    }
                    foreach (var componentsInChild in gameObject.GetComponentsInChildren<MeshFilter>())
                    {
                        int subTotalVerts = geom.NumVertexes;
                        foreach (Vector3 vector3 in componentsInChild.sharedMesh.vertices)
                        {
                            Vector3 vec = gameObject.transform.TransformPoint(vector3);
                            geom.Vertexes.Add(new RecastVertex(vec.x, vec.y, vec.z));
                            geom.NumVertexes++;
                        }
                        for (int j = 0; j < componentsInChild.sharedMesh.triangles.Length; j += 3)
                        {
                            geom.Triangles.Add(componentsInChild.sharedMesh.triangles[j] + subTotalVerts);
                            geom.Triangles.Add(componentsInChild.sharedMesh.triangles[j + 1] + subTotalVerts);
                            geom.Triangles.Add(componentsInChild.sharedMesh.triangles[j + 2] + subTotalVerts);
                            geom.NumTriangles++;
                        }
                    }
                    foreach (var offMeshConnector in gameObject.GetComponentsInChildren<OffMeshConnector>())
                    {
                        RecastVertex start = new RecastVertex(offMeshConnector.StartPosition.x, offMeshConnector.StartPosition.y, offMeshConnector.StartPosition.z);
                        RecastVertex end = new RecastVertex(offMeshConnector.EndPosition.x, offMeshConnector.EndPosition.y, offMeshConnector.EndPosition.z);
                        geom.AddOffMeshConnection(start, end, offMeshConnector.Radius, offMeshConnector.Bidirectional, 5, 8);
                    }
                }
            }
        }

        if (geom.NumVertexes != 0)
        {
            geom.CalculateBounds();
            config.CalculateGridSize(geom);
            geom.CreateChunkyTriMesh();
        }
    }
コード例 #13
0
ファイル: AtavismNavMesh.cs プロジェクト: zukeru/ageofasura
    public void BuildTile(int x, int y)
    {
        RecastVertex bmin = Geometry.MinBounds;
        RecastVertex bmax = Geometry.MaxBounds;
        float tcs = Config.TileSize * Config.CellSize;
        RecastVertex tileBMin = new RecastVertex();
        RecastVertex tileBMax = new RecastVertex();
        tileBMin.X = bmin.X + x * tcs;
        tileBMin.Y = bmin.Y;
        tileBMin.Z = bmin.Z + y * tcs;

        tileBMax.X = bmin.X + (x + 1) * tcs;
        tileBMax.Y = bmax.Y;
        tileBMax.Z = bmin.Z + (y + 1) * tcs;

        var builder = BuildTileMesh(x, y, tileBMin, tileBMax);

        // remove/add new tile?
        if (builder != null)
        {
            Detour.AtavismNavTile outBuilder;
            // nav mesh remove tile
            NavMesh.RemoveTile(NavMesh.GetTileRefAt(x, y, 0), out outBuilder);
            // nav mesh add tile
            long result = 0;
            NavMesh.AddTile(builder, NavMesh.TileFreeData, 0, ref result);
        }
    }
コード例 #14
0
ファイル: AtavismNavMesh.cs プロジェクト: zukeru/ageofasura
    public void RebuildTiles()
    {
        Progress = 0;
        IsBuilding = true;
        RecastVertex bmin = Geometry.MinBounds;
        RecastVertex bmax = Geometry.MaxBounds;
        RecastVertex tileBMin = new RecastVertex();
        RecastVertex tileBMax = new RecastVertex();
        float tcs = Config.TileSize * Config.CellSize;
        Total = TileWidth * TileHeight;
        for (int y = 0; y < TileHeight; y++)
        {
            for (int x = 0; x < TileWidth; x++)
            {
                Progress = y * TileWidth + x;
                tileBMin.X = bmin.X + x * tcs;
                tileBMin.Y = bmin.Y;
                tileBMin.Z = bmin.Z + y * tcs;

                tileBMax.X = bmin.X + (x + 1) * tcs;
                tileBMax.Y = bmax.Y;
                tileBMax.Z = bmin.Z + (y + 1) * tcs;
                #if UNITY_EDITOR
                EditorUtility.DisplayProgressBar("Generating...", "Generating Tile " + Progress + " of " + Total, Progress / (float)Total);
                #endif
                var builder = BuildTileMesh(x, y, tileBMin, tileBMax);

                // remove/add new tile?
                if (builder != null)
                {
                    Detour.AtavismNavTile outBuilder;
                    // nav mesh remove tile
                    NavMesh.RemoveTile(NavMesh.GetTileRefAt(x, y, 0), out outBuilder);
                    // nav mesh add tile
                    long result = 0;
                    NavMesh.AddTile(builder, NavMesh.TileFreeData, 0, ref result);
                }
            }
        }
        #if UNITY_EDITOR
        EditorUtility.ClearProgressBar();
        #endif
        IsBuilding = false;
        BuildGeometry();
    }
コード例 #15
0
ファイル: AtavismNavMesh.cs プロジェクト: zukeru/ageofasura
 private void YLoop(int y, float tcs, RecastVertex bmin, RecastVertex bmax)
 {
     bool canceled = false;
     #if UNITY_EDITOR
     for (int x = 0; x < TileWidth; x++)
     {
         canceled = EditorUtility.DisplayCancelableProgressBar("Generating...",
                                                               "Generating Tile " + Progress + " of " + Total,
                                                               Progress / (float)Total);
         if (canceled)
         {
             tokenSource.Cancel();
             break;
         }
         Xloop(y, x, tcs, bmin, bmax);
     }
     #endif
 }
コード例 #16
0
ファイル: AtavismNavMesh.cs プロジェクト: zukeru/ageofasura
    private void Xloop(int y, int x, float tcs, RecastVertex bmin, RecastVertex bmax)
    {
        RecastVertex tileBMin = new RecastVertex();
        RecastVertex tileBMax = new RecastVertex();
        tileBMin.X = bmin.X + x*tcs;
        tileBMin.Y = bmin.Y;
        tileBMin.Z = bmin.Z + y*tcs;

        tileBMax.X = bmin.X + (x + 1)*tcs;
        tileBMax.Y = bmax.Y;
        tileBMax.Z = bmin.Z + (y + 1)*tcs;
        #if UNITY_EDITOR
        bool canceled = EditorUtility.DisplayCancelableProgressBar("Generating...",
                                                              "Generating Tile " + Progress + " of " + Total,
                                                              Progress / (float)Total);
        if (canceled)
        {
            tokenSource.Cancel();
        }
        #endif
        var t = Task.Factory.StartNew(() => BuildTile(x, y, tileBMin, tileBMax), tokenSource.Token, TaskCreationOptions.LongRunning, scheduler);
        tasks.Add(t);
    }
コード例 #17
0
ファイル: AtavismNavMesh.cs プロジェクト: zukeru/ageofasura
    private Detour.AtavismNavTile BuildTileMesh(int tx, int ty, RecastVertex min, RecastVertex max)
    {
        Config.Width = Config.TileSize + Config.BorderSize * 2;
        Config.Height = Config.TileSize + Config.BorderSize * 2;
        Config.MinBounds = min;
        Config.MaxBounds = max;
        Config.MinBounds.X -= Config.BorderSize * Config.CellSize;
        Config.MinBounds.Z -= Config.BorderSize * Config.CellSize;

        Config.MaxBounds.X += Config.BorderSize * Config.CellSize;
        Config.MaxBounds.Z += Config.BorderSize * Config.CellSize;

        HeightField heightfield = new HeightField(Config.Width, Config.Height, Config.MinBounds.ToArray(), Config.MaxBounds.ToArray(), Config.CellSize, Config.CellHeight);

        short[] triAreas = new short[Geometry.ChunkyTriMesh.MaxTrisPerChunk];

        float[] tbmin = new float[2], tbmax = new float[2];
        tbmin[0] = Config.MinBounds.X;
        tbmin[1] = Config.MinBounds.Z;

        tbmax[0] = Config.MaxBounds.X;
        tbmax[1] = Config.MaxBounds.Z;

        int[] cid = new int[512];

        int ncid = Geometry.ChunkyTriMesh.GetChunksOverlappingRect(tbmin, tbmax, ref cid, 512);

        if (ncid == 0)
            return null;

        for (int i = 0; i < ncid; i++)
        {
            ChunkyTriMeshNode node = Geometry.ChunkyTriMesh.Nodes[cid[i]];
            int[] tris = new int[node.n * 3];
            Array.Copy(Geometry.ChunkyTriMesh.Tris, node.i * 3, tris, 0, node.n * 3);
            List<int> ctris = new List<int>(tris);
            int nctris = node.n;

            Array.Clear(triAreas, 0, triAreas.Length);
            Geometry.MarkWalkableTriangles(Config.WalkableSlopeAngle, ctris, nctris, ref triAreas);

            heightfield.RasterizeTriangles(Geometry, ctris, nctris, triAreas, Config.WalkableClimb);
        }

        heightfield.FilterLowHangingWalkableObstacles(Config.WalkableClimb);
        heightfield.FilterLedgeSpans(Config.WalkableHeight, Config.WalkableClimb);
        heightfield.FilterWalkableLowHeightSpans(Config.WalkableHeight);

        CompactHeightfield compactHeightfield = new CompactHeightfield(Config.WalkableHeight, Config.WalkableClimb, heightfield);
        compactHeightfield.ErodeWalkableArea(Config.WalkableRadius);

        // optional convex volumes

        compactHeightfield.BuildDistanceField();
        compactHeightfield.BuildRegions(Config.BorderSize, Config.MinRegionArea, Config.MergeRegionArea);

        ContourSet contourSet = new ContourSet(compactHeightfield, Config.MaxSimplificationError, Config.MaxEdgeLength);

        if (contourSet.NConts == 0)
            return null;

        PolyMesh polyMesh = new PolyMesh(contourSet, Config.MaxVertexesPerPoly);

        DetailPolyMesh detailPolyMesh = new DetailPolyMesh(polyMesh, compactHeightfield, Config.DetailSampleDistance,
                                                            Config.DetailSampleMaxError);

        // Convert the Areas and Flags for path weighting
        for (int i = 0; i < polyMesh.NPolys; i++)
        {

            if (polyMesh.Areas[i] == Geometry.WalkableArea)
            {
                polyMesh.Areas[i] = 0; // Sample_polyarea_ground
                polyMesh.Flags[i] = 1; // Samply_polyflags_walk
            }
        }
        NavMeshCreateParams param = new NavMeshCreateParams
        {
            Verts = polyMesh.Verts,
            VertCount = polyMesh.NVerts,
            Polys = polyMesh.Polys,
            PolyAreas = polyMesh.Areas,
            PolyFlags = polyMesh.Flags,
            PolyCount = polyMesh.NPolys,
            Nvp = polyMesh.Nvp,
            DetailMeshes = detailPolyMesh.Meshes,
            DetailVerts = detailPolyMesh.Verts,
            DetailVertsCount = detailPolyMesh.NVerts,
            DetailTris = detailPolyMesh.Tris,
            DetailTriCount = detailPolyMesh.NTris,

            // Off Mesh data
            OffMeshConVerts = Geometry.OffMeshConnectionVerts.ToArray(),
            OffMeshConRad = Geometry.OffMeshConnectionRadii.ToArray(),
            OffMeshConDir = Geometry.OffMeshConnectionDirections.ToArray(),
            OffMeshConAreas = Geometry.OffMeshConnectionAreas.ToArray(),
            OffMeshConFlags = Geometry.OffMeshConnectionFlags.ToArray(),
            OffMeshConUserId = Geometry.OffMeshConnectionIds.ToArray(),
            OffMeshConCount = (int)Geometry.OffMeshConnectionCount,
            // end off mesh data

            WalkableHeight = Config.WalkableHeight,
            WalkableRadius = Config.WalkableRadius,
            WalkableClimb = Config.WalkableClimb,
            BMin = new float[] { polyMesh.BMin[0], polyMesh.BMin[1], polyMesh.BMin[2] },
            BMax = new float[] { polyMesh.BMax[0], polyMesh.BMax[1], polyMesh.BMax[2] },
            Cs = polyMesh.Cs,
            Ch = polyMesh.Ch,
            BuildBvTree = true,
            TileX = tx,
            TileY = ty,
            TileLayer = 0
        };
        return new Detour.AtavismNavTile(param);
    }
コード例 #18
0
    private LunaNav.NavMeshBuilder BuildTileMesh(int tx, int ty, RecastVertex min, RecastVertex max)
    {
        Config.Width        = Config.TileSize + Config.BorderSize * 2;
        Config.Height       = Config.TileSize + Config.BorderSize * 2;
        Config.MinBounds    = min;
        Config.MaxBounds    = max;
        Config.MinBounds.X -= Config.BorderSize * Config.CellSize;
        Config.MinBounds.Z -= Config.BorderSize * Config.CellSize;

        Config.MaxBounds.X += Config.BorderSize * Config.CellSize;
        Config.MaxBounds.Z += Config.BorderSize * Config.CellSize;

        HeightField heightfield = new HeightField(Config.Width, Config.Height, Config.MinBounds.ToArray(), Config.MaxBounds.ToArray(), Config.CellSize, Config.CellHeight);


        short[] triAreas = new short[Geometry.ChunkyTriMesh.MaxTrisPerChunk];

        float[] tbmin = new float[2], tbmax = new float[2];
        tbmin[0] = Config.MinBounds.X;
        tbmin[1] = Config.MinBounds.Z;

        tbmax[0] = Config.MaxBounds.X;
        tbmax[1] = Config.MaxBounds.Z;

        int[] cid = new int[512];

        int ncid = Geometry.ChunkyTriMesh.GetChunksOverlappingRect(tbmin, tbmax, ref cid, 512);

        if (ncid == 0)
        {
            return(null);
        }

        for (int i = 0; i < ncid; i++)
        {
            ChunkyTriMeshNode node = Geometry.ChunkyTriMesh.Nodes[cid[i]];
            int[]             tris = new int[node.n * 3];
            Array.Copy(Geometry.ChunkyTriMesh.Tris, node.i * 3, tris, 0, node.n * 3);
            List <int> ctris  = new List <int>(tris);
            int        nctris = node.n;

            Array.Clear(triAreas, 0, triAreas.Length);
            Geometry.MarkWalkableTriangles(Config.WalkableSlopeAngle, ctris, nctris, ref triAreas);

            heightfield.RasterizeTriangles(Geometry, ctris, nctris, triAreas, Config.WalkableClimb);
        }

        heightfield.FilterLowHangingWalkableObstacles(Config.WalkableClimb);
        heightfield.FilterLedgeSpans(Config.WalkableHeight, Config.WalkableClimb);
        heightfield.FilterWalkableLowHeightSpans(Config.WalkableHeight);


        CompactHeightfield compactHeightfield = new CompactHeightfield(Config.WalkableHeight, Config.WalkableClimb, heightfield);

        compactHeightfield.ErodeWalkableArea(Config.WalkableRadius);

        // optional convex volumes

        compactHeightfield.BuildDistanceField();
        compactHeightfield.BuildRegions(Config.BorderSize, Config.MinRegionArea, Config.MergeRegionArea);


        ContourSet contourSet = new ContourSet(compactHeightfield, Config.MaxSimplificationError, Config.MaxEdgeLength);

        if (contourSet.NConts == 0)
        {
            return(null);
        }

        PolyMesh polyMesh = new PolyMesh(contourSet, Config.MaxVertexesPerPoly);

        DetailPolyMesh detailPolyMesh = new DetailPolyMesh(polyMesh, compactHeightfield, Config.DetailSampleDistance,
                                                           Config.DetailSampleMaxError);

        // Convert the Areas and Flags for path weighting
        for (int i = 0; i < polyMesh.NPolys; i++)
        {
            if (polyMesh.Areas[i] == Geometry.WalkableArea)
            {
                polyMesh.Areas[i] = 0; // Sample_polyarea_ground
                polyMesh.Flags[i] = 1; // Samply_polyflags_walk
            }
        }
        NavMeshCreateParams param = new NavMeshCreateParams
        {
            Verts            = polyMesh.Verts,
            VertCount        = polyMesh.NVerts,
            Polys            = polyMesh.Polys,
            PolyAreas        = polyMesh.Areas,
            PolyFlags        = polyMesh.Flags,
            PolyCount        = polyMesh.NPolys,
            Nvp              = polyMesh.Nvp,
            DetailMeshes     = detailPolyMesh.Meshes,
            DetailVerts      = detailPolyMesh.Verts,
            DetailVertsCount = detailPolyMesh.NVerts,
            DetailTris       = detailPolyMesh.Tris,
            DetailTriCount   = detailPolyMesh.NTris,

            // Off Mesh data
            OffMeshConVerts  = Geometry.OffMeshConnectionVerts.ToArray(),
            OffMeshConRad    = Geometry.OffMeshConnectionRadii.ToArray(),
            OffMeshConDir    = Geometry.OffMeshConnectionDirections.ToArray(),
            OffMeshConAreas  = Geometry.OffMeshConnectionAreas.ToArray(),
            OffMeshConFlags  = Geometry.OffMeshConnectionFlags.ToArray(),
            OffMeshConUserId = Geometry.OffMeshConnectionIds.ToArray(),
            OffMeshConCount  = (int)Geometry.OffMeshConnectionCount,
            // end off mesh data

            WalkableHeight = Config.WalkableHeight,
            WalkableRadius = Config.WalkableRadius,
            WalkableClimb  = Config.WalkableClimb,
            BMin           = new float[] { polyMesh.BMin[0], polyMesh.BMin[1], polyMesh.BMin[2] },
            BMax           = new float[] { polyMesh.BMax[0], polyMesh.BMax[1], polyMesh.BMax[2] },
            Cs             = polyMesh.Cs,
            Ch             = polyMesh.Ch,
            BuildBvTree    = true,
            TileX          = tx,
            TileY          = ty,
            TileLayer      = 0
        };

        return(new LunaNav.NavMeshBuilder(param));
    }
コード例 #19
0
        private void RasterizeTriangle(List <RecastVertex> vertexes, int v0, int v1, int v2, short area, float ics, float ich, int flagMergeThr)
        {
            int          w = Width;
            int          h = Height;
            RecastVertex tempMin, tempMax;

            float by = Bmax[1] - Bmin[1];

            tempMin = new RecastVertex(vertexes[v0]);
            tempMax = new RecastVertex(vertexes[v0]);
            tempMin = RecastVertex.Min(tempMin, vertexes[v1]);
            tempMin = RecastVertex.Min(tempMin, vertexes[v2]);
            tempMax = RecastVertex.Max(tempMax, vertexes[v1]);
            tempMax = RecastVertex.Max(tempMax, vertexes[v2]);

            if (!OverlapBounds(Bmin, Bmax, tempMin.ToArray(), tempMax.ToArray()))
            {
                return;
            }

            int x0 = (int)((tempMin[0] - Bmin[0]) * ics);
            int y0 = (int)((tempMin[2] - Bmin[2]) * ics);
            int x1 = (int)((tempMax[0] - Bmin[0]) * ics);
            int y1 = (int)((tempMax[2] - Bmin[2]) * ics);

            x0 = Math.Max(0, Math.Min(x0, w - 1));
            y0 = Math.Max(0, Math.Min(y0, h - 1));
            x1 = Math.Max(0, Math.Min(x1, w - 1));
            y1 = Math.Max(0, Math.Min(y1, h - 1));

            float[] inArray = new float[7 * 3], outArray = new float[7 * 3], inrowArray = new float[7 * 3];

            for (int y = y0; y <= y1; y++)
            {
                Array.Copy(vertexes[v0].ToArray(), 0, inArray, 0, 3);
                Array.Copy(vertexes[v1].ToArray(), 0, inArray, 1 * 3, 3);
                Array.Copy(vertexes[v2].ToArray(), 0, inArray, 2 * 3, 3);
                int   nvrow = 3;
                float cz    = Bmin[2] + y * Cs;
                nvrow = ClipPoly(inArray, nvrow, ref outArray, 0, 1, -cz);
                if (nvrow < 3)
                {
                    continue;
                }
                nvrow = ClipPoly(outArray, nvrow, ref inrowArray, 0, -1, cz + Cs);
                if (nvrow < 3)
                {
                    continue;
                }

                for (int x = x0; x <= x1; x++)
                {
                    int   nv = nvrow;
                    float cx = Bmin[0] + x * Cs;
                    nv = ClipPoly(inrowArray, nv, ref outArray, 1, 0, -cx);
                    if (nv < 3)
                    {
                        continue;
                    }
                    nv = ClipPoly(outArray, nv, ref inArray, -1, 0, cx + Cs);
                    if (nv < 3)
                    {
                        continue;
                    }

                    float smin = inArray[1], smax = inArray[1];
                    for (int i = 1; i < nv; i++)
                    {
                        smin = Math.Min(smin, inArray[i * 3 + 1]);
                        smax = Math.Max(smax, inArray[i * 3 + 1]);
                    }
                    smin -= Bmin[1];
                    smax -= Bmin[1];

                    if (smax.CompareTo(0.0f) < 0 || smin.CompareTo(by) > 0)
                    {
                        continue;
                    }
                    if (smin.CompareTo(0.0f) < 0)
                    {
                        smin = 0;
                    }
                    if (smax.CompareTo(by) > 0)
                    {
                        smax = by;
                    }

                    int ismin = Math.Max(0, Math.Min((int)Math.Floor(smin * ich), short.MaxValue));
                    int ismax = Math.Max(ismin + 1, Math.Min((int)Math.Floor(smax * ich), short.MaxValue));

                    AddSpan(x, y, ismin, ismax, area, flagMergeThr);
                }
            }
        }