コード例 #1
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));
    }
コード例 #2
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);
    }