/// <summary>
        /// Creates a new builder for a multi-tile mesh build.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Will return null if a processor requires the the detail mesh but the detail mesh is
        /// not included in the result options.
        /// </para>
        /// </remarks>
        /// <param name="tx">The x-index of the tile to build.</param>
        /// <param name="tz">The z-index of the tile to build.</param>
        /// <param name="resultOptions">The assets to include in the result.</param>
        /// <param name="tdef">The tile set definition to base the build on.</param>
        /// <param name="processors">The processors to apply.</param>
        /// <returns>A new builder, or null on error.</returns>
        public static IncrementalBuilder Create(int tx, int tz
                                                , NMGenAssetFlag resultOptions
                                                , TileSetDefinition tdef
                                                , ProcessorSet processors)
        {
            if (tdef == null || processors == null)
            {
                return(null);
            }

            resultOptions |= NMGenAssetFlag.PolyMesh;

            if ((processors.PreserveAssets & NMGenAssetFlag.DetailMesh) != 0 &&
                (resultOptions & NMGenAssetFlag.DetailMesh) == 0)
            {
                // The processors require the detail mesh, but the result won't include it.
                return(null);
            }

            Vector3 bmin;
            Vector3 bmax;

            // This next call checks for valid tx/tz.
            if (!tdef.GetTileBounds(tx, tz, true, out bmin, out bmax))
            {
                return(null);
            }

            NMGenTileParams tileConfig = new NMGenTileParams(tx, tz, bmin, bmax);

            return(new IncrementalBuilder(tileConfig, tdef.GetBaseConfig(), resultOptions
                                          , tdef.Geometry, processors));
        }
        /// <summary>
        /// Creates a new builder for a single-tile mesh build.
        /// </summary>
        /// <remarks>
        /// <para>
        /// The bounds of the tile will be based on the geometry.
        /// </para>
        /// <para>
        /// Will return null if a processor requires the the detail mesh but
        /// the detail mesh is not included in the result options.
        /// </para>
        /// </remarks>
        /// <param name="buildConfig">The build configuration.</param>
        /// <param name="resultOptions">The assets to include in the result.</param>
        /// <param name="geometry">The input geometry.</param>
        /// <param name="processors">The processors to apply.</param>
        /// <returns>A new builder, or null on error.</returns>
        public static IncrementalBuilder Create(NMGenParams buildConfig
                                                , NMGenAssetFlag resultOptions
                                                , InputGeometry geometry
                                                , ProcessorSet processors)
        {
            if (buildConfig == null ||
                geometry == null ||
                processors == null)
            {
                return(null);
            }

            resultOptions |= NMGenAssetFlag.PolyMesh;

            if ((processors.PreserveAssets & NMGenAssetFlag.DetailMesh) != 0 &&
                (resultOptions & NMGenAssetFlag.DetailMesh) == 0)
            {
                // The processors require the detail mesh, but the result won't include it.
                return(null);
            }

            NMGenTileParams tileConfig =
                new NMGenTileParams(0, 0, geometry.BoundsMin, geometry.BoundsMax);

            return(new IncrementalBuilder(tileConfig
                                          , buildConfig, resultOptions, geometry, processors));
        }
        private IncrementalBuilder(NMGenTileParams tileConfig
                                   , NMGenParams config
                                   , NMGenAssetFlag resultOptions
                                   , InputGeometry source
                                   , ProcessorSet processors)
        {
            mConfig     = config;
            mTileConfig = tileConfig;

            mGeometry      = source;
            mProcessors    = processors;
            mResultOptions = resultOptions;

            mBuildContext = new NMGenContext(tileConfig.TileX, tileConfig.TileZ, mConfig.Clone());

            mTileText = string.Format("({0},{1})", tileConfig.TileX, tileConfig.TileZ);

            mState = NMGenState.Initialized;
        }
        private IncrementalBuilder(NMGenTileParams tileConfig
            , NMGenParams config
            , NMGenAssetFlag resultOptions
            , InputGeometry source
            , ProcessorSet processors)
        {
            mConfig = config;
            mTileConfig = tileConfig;

            mGeometry = source;
            mProcessors = processors;
            mResultOptions = resultOptions;

            mBuildContext = new NMGenContext(tileConfig.TileX, tileConfig.TileZ, mConfig.Clone());

            mTileText = string.Format("({0},{1})", tileConfig.TileX, tileConfig.TileZ);

            mState = NMGenState.Initialized;
        }
        /// <summary>
        /// Creates a new builder for a multi-tile mesh build.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Will return null if a processor requires the the detail mesh but the detail mesh is 
        /// not included in the result options.
        /// </para>
        /// </remarks>
        /// <param name="tx">The x-index of the tile to build.</param>
        /// <param name="tz">The z-index of the tile to build.</param>
        /// <param name="resultOptions">The assets to include in the result.</param>
        /// <param name="tdef">The tile set definition to base the build on.</param>
        /// <param name="processors">The processors to apply.</param>
        /// <returns>A new builder, or null on error.</returns>
        public static IncrementalBuilder Create(int tx, int tz
            , NMGenAssetFlag resultOptions
            , TileSetDefinition tdef
            , ProcessorSet processors)
        {
            if (tdef == null || processors == null)
                return null;

            resultOptions |= NMGenAssetFlag.PolyMesh;

            if ((processors.PreserveAssets & NMGenAssetFlag.DetailMesh) != 0
                && (resultOptions & NMGenAssetFlag.DetailMesh) == 0)
            {
                // The processors require the detail mesh, but the result won't include it.
                return null;
            }

            Vector3 bmin;
            Vector3 bmax;

            // This next call checks for valid tx/tz.
            if (!tdef.GetTileBounds(tx, tz, true, out bmin, out bmax))
                return null;

            NMGenTileParams tileConfig = new NMGenTileParams(tx, tz, bmin, bmax);

            return new IncrementalBuilder(tileConfig, tdef.GetBaseConfig(), resultOptions
                , tdef.Geometry, processors);
        }
        /// <summary>
        /// Creates a new builder for a single-tile mesh build.
        /// </summary>
        /// <remarks>
        /// <para>
        /// The bounds of the tile will be based on the geometry.
        /// </para>
        /// <para>
        /// Will return null if a processor requires the the detail mesh but
        /// the detail mesh is not included in the result options.
        /// </para>
        /// </remarks>
        /// <param name="buildConfig">The build configuration.</param>
        /// <param name="resultOptions">The assets to include in the result.</param>
        /// <param name="geometry">The input geometry.</param>
        /// <param name="processors">The processors to apply.</param>
        /// <returns>A new builder, or null on error.</returns>
        public static IncrementalBuilder Create(NMGenParams buildConfig
            , NMGenAssetFlag resultOptions
            , InputGeometry geometry
            , ProcessorSet processors)
        {
            if (buildConfig == null
                || geometry == null
                || processors == null)
            {
                return null;
            }

            resultOptions |= NMGenAssetFlag.PolyMesh;

            if ((processors.PreserveAssets & NMGenAssetFlag.DetailMesh) != 0
                && (resultOptions & NMGenAssetFlag.DetailMesh) == 0)
            {
                // The processors require the detail mesh, but the result won't include it.
                return null;
            }

            NMGenTileParams tileConfig =
                new NMGenTileParams(0, 0, geometry.BoundsMin, geometry.BoundsMax);

            return new IncrementalBuilder(tileConfig
                , buildConfig, resultOptions, geometry, processors);
        }