Example #1
0
        /// <summary>
        /// Creates a compact open heightfield from a solid heightfield.
        /// </summary>
        /// <param name="context">The context to use duing the operation.</param>
        /// <param name="sourceField">
        /// The solid heighfield to derive the compact heightfield from.
        /// </param>
        /// <param name="walkableHeight">
        /// The minimum floor to ceiling height that is still considered walkable.
        /// [Limit: >= <see cref="NMGen.MinWalkableHeight"/>]
        /// </param>
        /// <param name="walkableStep">
        /// The maximum floor to floor step that is still considered walkable.</param>
        /// <returns>True if the operation completed successfully.</returns>
        public static CompactHeightfield Build(BuildContext context
                                               , Heightfield sourceField
                                               , int walkableHeight
                                               , int walkableStep)
        {
            if (context == null ||
                sourceField == null || sourceField.IsDisposed ||
                walkableHeight < NMGen.MinWalkableHeight ||
                walkableStep < 0)
            {
                return(null);
            }

            CompactHeightfield field = new CompactHeightfield();

            if (CompactHeightfieldEx.nmcfBuildField(context.root
                                                    , walkableHeight
                                                    , walkableStep
                                                    , sourceField.root
                                                    , field))
            {
                return(field);
            }

            return(null);
        }
Example #2
0
 /// <summary>
 /// Builds the distance field for the heightfield.
 /// </summary>
 /// <remarks>
 /// <para>
 /// This method must be called before attempting to build region data.
 /// </para>
 /// <para>
 /// The distance data is avaiable via <see cref="MaxDistance"/> and
 /// <see cref="GetDistanceData"/>.
 /// </para>
 /// </remarks>
 /// <param name="context">The context to use duing the operation.</param>
 /// <returns>True if the operation completed successfully.</returns>
 public bool BuildDistanceField(BuildContext context)
 {
     if (IsDisposed)
     {
         return(false);
     }
     return(CompactHeightfieldEx.nmcfBuildDistanceField(context.root, this));
 }
Example #3
0
 /// <summary>
 /// Applies a median filter to the walkable areas. (Removes noise.)
 /// </summary>
 /// <param name="context">The context to use duing the operation. </param>
 /// <returns>True if the operation completed successfully.</returns>
 public bool ApplyMedianFilter(BuildContext context)
 {
     if (IsDisposed)
     {
         return(false);
     }
     return(CompactHeightfieldEx.nmcfMedianFilterWalkableArea(context.root, this));
 }
Example #4
0
 /// <summary>
 /// Erodes the walkable area within the heightfield by the specified radius.
 /// </summary>
 /// <remarks>
 /// <para>
 /// Basically, any spans that are closer to a boundary or obstruction than the specified
 /// radius are marked as unwalkable.
 /// </para>
 /// <para>
 /// This method is usually called immediately after the heightfield has been created.
 /// </para>
 /// </remarks>
 /// <param name="context">The context to use during the operation. </param>
 /// <param name="radius">The radius to apply. [Units: Spans]</param>
 /// <returns>True if the operation completed successfully.</returns>
 public bool ErodeWalkableArea(BuildContext context, int radius)
 {
     if (IsDisposed)
     {
         return(false);
     }
     return(CompactHeightfieldEx.nmcfErodeWalkableArea(context.root
                                                       , radius
                                                       , this));
 }
Example #5
0
        /// <summary>
        /// Loads the heightfield's <see cref="CompactSpan"/> data into the provided buffer.
        /// </summary>
        /// <param name="buffer">The buffer to load the data into. [Size: >= SpanCount]</param>
        /// <returns>True if the buffer was successfully loaded.</returns>
        public bool GetSpanData(CompactSpan[] buffer)
        {
            if (IsDisposed)
            {
                return(false);
            }

            return(CompactHeightfieldEx.nmcfGetSpanData(this
                                                        , buffer
                                                        , buffer.Length));
        }
Example #6
0
 /// <summary>
 /// Builds region data for the heightfield using watershed partitioning.
 /// </summary>
 /// <remarks>
 /// <para>
 /// Non-null regions consist of connected, non-overlapping walkable spans that form a
 /// single contour.
 /// </para>
 /// <para>
 /// The region data is available via <see cref="MaxRegion"/> and <see cref="GetSpanData"/>.
 /// </para>
 /// <para>
 /// If a region forms an area that is smaller than <paramref name="minRegionArea"/>,
 /// all spans in the region is set to <see cref="NMGen.NullRegion"/>.
 /// </para>
 /// <para>
 /// Watershed partitioning can result in smaller than necessary regions, especially
 /// in diagonal corridors.  <paramref name="mergeRegionArea"/> helps reduce unecessarily
 /// small regions.
 /// </para>
 /// </remarks>
 /// <param name="context">The context to use duing the operation.</param>
 /// <param name="borderSize">The AABB border size to apply.</param>
 /// <param name="minRegionArea">
 /// The minimum area allowed for unconnected (island) regions. [Units: Spans]
 /// </param>
 /// <param name="mergeRegionArea">
 /// The maximum region size that will be considered for merging with another region.
 /// [Units: Spans]
 /// </param>
 /// <returns>True if the operation completed successfully.</returns>
 public bool BuildRegions(BuildContext context
                          , int borderSize, int minRegionArea, int mergeRegionArea)
 {
     if (IsDisposed)
     {
         return(false);
     }
     return(CompactHeightfieldEx.nmcfBuildRegions(context.root
                                                  , this
                                                  , borderSize
                                                  , minRegionArea
                                                  , mergeRegionArea));
 }
Example #7
0
 /// <summary>
 /// Applied the area to all spans within the specified cylinder.
 /// </summary>
 /// <remarks>
 /// <para>
 /// The method will return false if the cylinder is completely outside of the heightfield.
 /// </para>
 /// </remarks>
 /// <param name="context">The context to use duing the operation.</param>
 /// <param name="centerBase">The center of the base of the cylinder.</param>
 /// <param name="radius">The radius of the cylinder.</param>
 /// <param name="height">The height of the cylinder.</param>
 /// <param name="area">The area to apply.</param>
 /// <returns>True if the operation completed successfully.</returns>
 public bool MarkCylinderArea(BuildContext context
                              , Vector3 centerBase, float radius, float height
                              , byte area)
 {
     if (IsDisposed)
     {
         return(false);
     }
     return(CompactHeightfieldEx.nmcfMarkCylinderArea(context.root
                                                      , ref centerBase
                                                      , radius
                                                      , height
                                                      , area
                                                      , this));
 }
Example #8
0
        /// <summary>
        /// Applies the area to all spans within the specified bounding box. (AABB)
        /// </summary>
        /// <remarks>
        /// <para>
        /// The method will return false if the AABB is completely outside of the heightfield.
        /// </para>
        /// </remarks>
        /// <param name="context">The context to use duing the operation.</param>
        /// <param name="boundsMin">The minimum bounds of the AABB.</param>
        /// <param name="boundsMax">The maximum bounds of the AABB. </param>
        /// <param name="area">The area to apply.</param>
        /// <returns>True if the operation completed successfully.</returns>
        public bool MarkBoxArea(BuildContext context
                                , Vector3 boundsMin, Vector3 boundsMax
                                , byte area)
        {
            if (IsDisposed)
            {
                return(false);
            }

            return(CompactHeightfieldEx.nmcfMarkBoxArea(context.root
                                                        , ref boundsMin
                                                        , ref boundsMax
                                                        , area
                                                        , this));
        }
Example #9
0
 /// <summary>
 /// Applies the area to the all spans within the specified convex polygon.
 /// </summary>
 /// <remarks>
 /// <para>
 /// The y-values of the polygon vertices are ignored.  So the polygon is effectively
 /// projected onto the xz-plane at yMin, then extruded to yMax.
 /// </para>
 /// <para>
 /// The method will return false if the polygon is completely outside of the heightfield.
 /// </para>
 /// </remarks>
 /// <param name="context">The context to use duing the operation.</param>
 /// <param name="verts">The vertices of the polygon [Length: vertCount]</param>
 /// <param name="yMin">The height of the base of the polygon.</param>
 /// <param name="yMax">The height of the top of the polygon.</param>
 /// <param name="area">The area to apply.</param>
 /// <returns>True if the operation completed successfully.</returns>
 public bool MarkConvexPolyArea(BuildContext context
                                , Vector3[] verts, float yMin, float yMax
                                , byte area)
 {
     if (IsDisposed)
     {
         return(false);
     }
     return(CompactHeightfieldEx.nmcfMarkConvexPolyArea(context.root
                                                        , verts
                                                        , verts.Length
                                                        , yMin
                                                        , yMax
                                                        , area
                                                        , this));
 }
Example #10
0
 /// <summary>
 /// Frees all unmanaged resources controlled by the object and marks it as disposed.
 /// </summary>
 public void RequestDisposal()
 {
     if (!IsDisposed)
     {
         CompactHeightfieldEx.nmcfFreeFieldData(this);
         mWidth          = 0;
         mDepth          = 0;
         mBorderSize     = 0;
         mBoundsMin      = Vector3Util.Zero;
         mBoundsMax      = Vector3Util.Zero;
         mMaxDistance    = 0;
         mMaxRegions     = 0;
         mSpanCount      = 0;
         mWalkableHeight = 0;
         mWalkableStep   = 0;
         mXZCellSize     = 0;
         mYCellSize      = 0;
     }
 }