예제 #1
0
        private bool BuildSingleTile()
        {
            TileBuildData tdata  = mBuild.BuildData;
            NMGenConfig   config = mBuild.Config;
            InputGeometry geom   = mBuild.InputGeom;

            mContext.ResetLog();

            /*
             * Design note:
             *
             * Not using the build task since it doesn't provide enough progress
             * feedback for a single tile.
             *
             */

            // Create the NMGen builder.

            IncrementalBuilder builder = IncrementalBuilder.Create(config.GetConfig()
                                                                   , config.ResultOptions
                                                                   , geom
                                                                   , mBuild.NMGenProcessors);

            if (builder == null)
            {
                mContext.PostError("Unexpected failure creating NMGen builder.", mBuild);
                tdata.SetAsFailed(0, 0);
                return(false);
            }
            else if (builder.IsFinished)
            {
                if (builder.State == NMGenState.NoResult)
                {
                    mContext.PostError("NMGen build did not produce a result. (Early exit.)"
                                       , builder.GetMessages(), mBuild);
                    tdata.SetAsFailed(0, 0);
                    return(false);
                }
                else
                {
                    mContext.PostError("Unexpected NMGen builder completion."
                                       , builder.GetMessages(), mBuild);
                    tdata.SetAsFailed(0, 0);
                    return(false);
                }
            }

            mBuild.BuildData.SetAsInProgress(0, 0);

            // Run the NMGen builder.

            while (!builder.IsFinished)
            {
                if (EditorUtility.DisplayCancelableProgressBar("Build Single Tile Mesh"
                                                               , IncrementalBuilder.ToLabel(builder.State)
                                                               , IncrementalBuilder.ToProgress(builder.State)))
                {
                    return(false);
                }

                builder.Build();
            }

            // Handle NMGen failures.

            mContext.Log(builder.GetMessages());   // Single tile build.  So go ahead an record.

            switch (builder.State)
            {
            case NMGenState.Aborted:

                mContext.PostError("NMGen build failed.", mBuild);
                tdata.SetAsFailed(0, 0);
                return(false);

            case NMGenState.NoResult:

                mContext.PostError("NMGen build did not produce a result.", mBuild);
                tdata.SetAsFailed(0, 0);
                return(false);
            }

            mContext.Log(string.Format("Completed NMGen build: {0} polygons."
                                       , builder.Result.PolyMesh.PolyCount)
                         , mBuild);

            // Build the tile.

            NMGenAssets result = builder.Result;

            if (result.DetailMesh == null)
            {
                Debug.LogError("result.DetailMesh ==null!");
            }

            NavmeshTileBuildData tbd = org.critterai.nmbuild.NMBuild.GetBuildData(
                mContext, 0, 0
                , result.PolyMesh.GetData(false), result.DetailMesh.GetData(false)
                , mBuild.Connections
                , (config.BuildFlags & NMGenBuildFlag.BVTreeEnabled) != 0);

            if (tbd == null)
            {
                // No need to log the error.  The above method takes care of that.
                tdata.SetAsFailed(0, 0);
                return(false);
            }

            NavmeshTileData td = NavmeshTileData.Create(tbd);

            if (td.Size == 0)
            {
                mContext.PostError(
                    "Could not create {0} object. Cause unknown." + typeof(NavmeshTileData)
                    , mBuild);
                tdata.SetAsFailed(0, 0);
                return(false);
            }

            // Finalize the tile.

            tdata.SetWorkingData(0, 0, result.PolyMesh, result.DetailMesh);
            tdata.SetWorkingData(0, 0, td, tbd.PolyCount);

            mContext.PostTrace("Completed single tile build.", mBuild);

            return(true);
        }
예제 #2
0
        private bool BuildMultiTiled()
        {
            TileSetDefinition tdef  = mBuild.TileSetDefinition;
            TileBuildData     tdata = mBuild.BuildData;

            mContext.ResetLog();

            int total = tdef.Width * tdef.Depth;

            string msg = string.Format("Multi-tile build: {0} tiles ({1}x{2})"
                                       , total, tdef.Width, tdef.Depth);

            mContext.Log(msg, mBuild);

            int count = 0; // For the progress bar.

            for (int tx = 0; tx < tdef.Width; tx++)
            {
                for (int tz = 0; tz < tdef.Depth; tz++)
                {
                    count++;

                    string tileText = string.Format("({0},{1})", tx, tz);

                    if (EditorUtility.DisplayCancelableProgressBar("Multi-tiled Build & Bake"
                                                                   , string.Format("Tile: {0}  ({1} of {2})", tileText, count, total)
                                                                   , (float)count / total))
                    {
                        return(false);
                    }

                    // Create the NMGen builder.

                    IncrementalBuilder builder = IncrementalBuilder.Create(tx, tz
                                                                           , mBuild.Config.ResultOptions
                                                                           , mBuild.TileSetDefinition
                                                                           , mBuild.NMGenProcessors);

                    if (builder == null)
                    {
                        mContext.PostError(
                            "Unexpected failure creating NMGen builder: Tile: " + tileText
                            , mBuild);
                        tdata.SetAsFailed(tx, tz);
                        return(false);
                    }

                    mBuild.BuildData.SetAsInProgress(tx, tz);

                    // Create and run the build task.

                    NMGenTask ntask = NMGenTask.Create(builder, 0);

                    ntask.Run();

                    if (ntask.TaskState == BuildTaskState.Aborted)
                    {
                        mContext.PostError("NMGen build task failed: Tile: " + tileText
                                           , ntask.Messages, mBuild);
                        tdata.SetAsFailed(tx, tz);
                        return(false);
                    }

                    NMGenAssets nr = ntask.Result;

                    if (nr.NoResult)
                    {
                        mContext.PostTrace("NMGen complete. Empty tile: " + tileText
                                           , builder.GetMessages()
                                           , mBuild);
                        tdata.SetAsEmpty(tx, tz);
                        continue;
                    }

                    msg = string.Format("NMGen complete. Tile {0} has {1} polygons."
                                        , tileText, nr.PolyMesh.PolyCount);

                    mContext.PostTrace(msg, builder.GetMessages(), mBuild);

                    TileBuildTask ttask = TileBuildTask.Create(tx, tz
                                                               , nr.PolyMesh.GetData(false), nr.DetailMesh.GetData(false)
                                                               , mBuild.Connections
                                                               , (mBuild.Config.BuildFlags & NMGenBuildFlag.BVTreeEnabled) != 0
                                                               , false, 0);

                    ttask.Run();

                    if (ttask.TaskState == BuildTaskState.Aborted)
                    {
                        mContext.PostError("Tile build task failed: Tile: " + tileText
                                           , ttask.Messages
                                           , mBuild);
                        tdata.SetAsFailed(tx, tz);
                        return(false);
                    }

                    TileBuildAssets tr = ttask.Result;

                    tdata.SetWorkingData(tx, tz, nr.PolyMesh, nr.DetailMesh);
                    tdata.SetWorkingData(tx, tz, tr.Tile, tr.PolyCount);
                }
            }

            int bakeable = tdata.BakeableCount();

            if (bakeable == 0)
            {
                mContext.PostError("Build did not produce any usuable tiles. (All tiles empty?)"
                                   , mBuild);
                return(false);
            }

            msg = string.Format("Tile build complete. {0} tiles produced. {1} empty tiles."
                                , bakeable, tdata.GetStateCount(TileBuildState.Empty));

            mContext.PostTrace(msg, mBuild);

            return(true);
        }
예제 #3
0
        private void ManageNMGenRequests()
        {
            mLogger.ResetLog();

            TileBuildData tdata = mContext.Build.BuildData;

            // Due to concurrency with the input build, this method
            // does not log things via the context.

            List <NMGenTask> requests = mContext.NMGenTasks;

            for (int i = requests.Count - 1; i >= 0; i--)
            {
                NMGenTask item = requests[i];

                if (item.IsFinished)
                {
                    requests.RemoveAt(i);

                    NavmeshBuild build = mContext.Build;

                    if (!build)
                    {
                        // Asset was deleted.
                        continue;
                    }

                    string tileText = string.Format("({0},{1})", item.TileX, item.TileZ);

                    switch (item.TaskState)
                    {
                    case BuildTaskState.Aborted:

                        mLogger.Log(item.Messages);
                        mLogger.PostError("Tile build failed: " + tileText, build);

                        tdata.SetAsFailed(item.TileX, item.TileZ);

                        break;

                    case BuildTaskState.Complete:

                        NMGenAssets r = item.Result;

                        if (r.NoResult)
                        {
                            mLogger.PostTrace("NMGen build complete. Tile is empty: " + tileText
                                              , item.Messages, build);

                            tdata.SetAsEmpty(r.TileX, r.TileZ);
                        }
                        else
                        {
                            tdata.SetWorkingData(r.TileX, r.TileZ, r.PolyMesh, r.DetailMesh);

                            mLogger.PostTrace("NMGen build complete: " + tileText
                                              , item.Messages, build);

                            mContext.QueueTask(mLogger, r.TileX, r.TileZ
                                               , r.PolyMesh, r.DetailMesh
                                               , (build.Config.BuildFlags & NMGenBuildFlag.BVTreeEnabled) != 0
                                               , item.Priority);
                        }

                        break;
                    }
                }
                else if (item.TaskState == BuildTaskState.InProgress &&
                         tdata.GetState(item.TileX, item.TileZ) != TileBuildState.InProgress)
                {
                    // Transition to the in-progress state.
                    tdata.SetAsInProgress(item.TileX, item.TileZ);
                }
            }
        }