예제 #1
0
        public static int[] calcTileCount(float[] bmin, float[] bmax, float cs, int tileSize)
        {
            int[] gwh = Recast.calcGridSize(bmin, bmax, cs);
            int   gw  = gwh[0];
            int   gh  = gwh[1];
            int   ts  = tileSize;
            int   tw  = (gw + ts - 1) / ts;
            int   th  = (gh + ts - 1) / ts;

            return(new int[] { tw, th });
        }
예제 #2
0
        private CompactHeightfield buildCompactHeightfield(InputGeom geom, RecastBuilderConfig bcfg, Context ctx)
        {
            RecastConfig cfg = bcfg.cfg;
            //
            // Step 2. Rasterize input polygon soup.
            //

            // Allocate voxel heightfield where we rasterize our input data to.
            Heightfield solid = new Heightfield(bcfg.width, bcfg.height, bcfg.bmin, bcfg.bmax, cfg.cs, cfg.ch);

            // Allocate array that can hold triangle area types.
            // If you have multiple meshes you need to process, allocate
            // and array which can hold the max number of triangles you need to
            // process.

            // Find triangles which are walkable based on their slope and rasterize
            // them.
            // If your input data is multiple meshes, you can transform them here,
            // calculate
            // the are type for each of the meshes and rasterize them.
            float[] verts     = geom.Verts;
            bool    tiled     = cfg.tileSize > 0;
            int     totaltris = 0;

            if (tiled)
            {
                ChunkyTriMesh chunkyMesh = geom.ChunkyMesh;
                float[]       tbmin      = new float[2];
                float[]       tbmax      = new float[2];
                tbmin[0] = bcfg.bmin[0];
                tbmin[1] = bcfg.bmin[2];
                tbmax[0] = bcfg.bmax[0];
                tbmax[1] = bcfg.bmax[2];
                List <ChunkyTriMeshNode> nodes = chunkyMesh.getChunksOverlappingRect(tbmin, tbmax);
                foreach (ChunkyTriMeshNode node in nodes)
                {
                    int[] tris  = node.tris;
                    int   ntris = tris.Length / 3;
                    totaltris += ntris;
                    int[] m_triareas = Recast.markWalkableTriangles(ctx, cfg.walkableSlopeAngle, verts, tris, ntris);
                    RecastRasterization.rasterizeTriangles(ctx, verts, tris, m_triareas, ntris, solid, cfg.walkableClimb);
                }
            }
            else
            {
                int[] tris       = geom.Tris;
                int   ntris      = tris.Length / 3;
                int[] m_triareas = Recast.markWalkableTriangles(ctx, cfg.walkableSlopeAngle, verts, tris, ntris);
                totaltris = ntris;
                RecastRasterization.rasterizeTriangles(ctx, verts, tris, m_triareas, ntris, solid, cfg.walkableClimb);
            }
            //
            // Step 3. Filter walkables surfaces.
            //

            // Once all geometry is rasterized, we do initial pass of filtering to
            // remove unwanted overhangs caused by the conservative rasterization
            // as well as filter spans where the character cannot possibly stand.
            RecastFilter.filterLowHangingWalkableObstacles(ctx, cfg.walkableClimb, solid);
            RecastFilter.filterLedgeSpans(ctx, cfg.walkableHeight, cfg.walkableClimb, solid);
            RecastFilter.filterWalkableLowHeightSpans(ctx, cfg.walkableHeight, solid);

            //
            // Step 4. Partition walkable surface to simple regions.
            //

            // Compact the heightfield so that it is faster to handle from now on.
            // This will result more cache coherent data as well as the neighbours
            // between walkable cells will be calculated.
            CompactHeightfield chf = Recast.buildCompactHeightfield(ctx, cfg.walkableHeight, cfg.walkableClimb, solid);

            // Erode the walkable area by agent radius.
            RecastArea.erodeWalkableArea(ctx, cfg.walkableRadius, chf);
            // (Optional) Mark areas.
            foreach (ConvexVolume vol in geom.ConvexVolumes)
            {
                RecastArea.markConvexPolyArea(ctx, vol.verts, vol.hmin, vol.hmax, vol.area, chf);
            }
            return(chf);
        }