private void HandleBake()
        {
            const string Category = "Bake To Target";

            NavmeshBuild  build = Context.Build; // Caller checks for null.
            TileBuildData tdata = build.BuildData;

            // Double check.
            if (tdata.BakeableCount() == 0)
            {
                Debug.LogWarning(Category + ": No tiles were produced.  (All tiles empty?)", build);
                return;
            }

            if (Context.TaskCount > 0)
            {
                Debug.LogWarning(Category + ": There are in-progress background builds."
                                 + " The tiles associated with these builds will not be baked."
                                 + " In-progress builds: " + Context.TaskCount
                                 , build);
            }

            NavmeshParams nconfig;

            NavmeshTileData[] tiles;

            bool success = tdata.GetMeshBuildData(build.TileSetDefinition.BoundsMin
                                                  , build.TileSetDefinition.TileWorldSize
                                                  , out nconfig, out tiles);

            if (!success)
            {
                Logger.PostError("Bake to target: Error creating navigation mesh from build data."
                                 , Context.Build);
                return;
            }

            NavStatus status =
                build.BuildTarget.Load(nconfig, tiles, NMBEditorUtil.GetConfig(build));

            if ((status & NavStatus.Failure) == 0)
            {
                build.BuildData.SetAsBaked();
                EditorUtility.SetDirty((Object)build.BuildTarget);
            }
            else
            {
                Logger.PostError("Bake to target: Target reported failure."
                                 , (Object)Context.Build.BuildTarget);
            }
        }
Beispiel #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);
        }
Beispiel #3
0
        private void HandleWorkingNavmesh(TileSelection selection)
        {
            NavmeshBuild  build = selection.Build;
            TileBuildData tdata = build.BuildData;

            if (mDebugObject == null)
            {
                Navmesh navmesh = null;

                if (tdata.BakeableCount() == 0)
                {
                    // Nothing to display.
                    return;
                }

                bool success = true;

                TileSetDefinition tdef = build.TileSetDefinition;

                NavmeshParams     nconfig;
                NavmeshTileData[] tiles;

                if (tdef == null)
                {
                    tiles = new NavmeshTileData[1] {
                        tdata.GetTileData(0, 0)
                    };
                    nconfig = NavUtil.DeriveConfig(tiles[0]);
                }
                else
                {
                    TileZone zone;

                    if (selection.HasSelection)
                    {
                        zone = selection.Zone;
                    }
                    else
                    {
                        zone = new TileZone(0, 0, tdef.Width - 1, tdef.Depth - 1);
                    }

                    success = tdata.GetMeshBuildData(tdef.BoundsMin.ToUnityVector3(), tdef.TileWorldSize, zone
                                                     , out nconfig, out tiles);
                }

                NavStatus status = NavStatus.Sucess;

                if (success)
                {
                    status = Navmesh.Create(nconfig, out navmesh);

                    if ((status & NavStatus.Failure) == 0)
                    {
                        foreach (NavmeshTileData tile in tiles)
                        {
                            uint trash;
                            status = navmesh.AddTile(tile, Navmesh.NullTile, out trash);

                            if ((status & NavStatus.Sucess) == 0)
                            {
                                navmesh = null;
                                break;
                            }
                        }
                    }
                }

                if ((status & NavStatus.Sucess) == 0)
                {
                    Show = MeshDebugOption.None;                      // Use property.
                    Debug.LogError("Mesh Debug View: Error creating working navigation mesh: "
                                   + status + ". Disabled display.", build);
                }
                else
                {
                    mDebugObject = navmesh;
                }
            }

            if (mDebugObject != null)
            {
                Navmesh nm = ( Navmesh )mDebugObject;
                NavDebug.Draw(nm, NavmeshSceneDraw.Instance.ColorByArea);
            }
        }
        protected override void OnGUIButtons()
        {
            DebugContext.SetViews(ViewOption.Grid | ViewOption.Selection | ViewOption.Mesh);

            NavmeshBuild build = Context.Build;

            if (!build)
            {
                return;
            }

            TileBuildData tdata = build.BuildData;

            if (tdata == null)
            {
                return;
            }

            TileSelection selection = Context.Selection;

            bool hasSelection  = selection.Validate();
            bool needBaking    = (tdata.NeedsBakingCount() > 0);
            int  activeCount   = Context.TaskCount;
            int  bakeableCount = tdata.BakeableCount();

            bool origGUIEnabled = GUI.enabled;

            bool guiEnabled = !IsBaseBusy;

            GUI.enabled = guiEnabled;

            ControlUtil.BeginButtonArea(Context.ButtonArea);

            if (GUILayout.Button("Build All"))
            {
                HandleBuildRequest(true);
            }

            GUI.enabled = guiEnabled && hasSelection;

            if (GUILayout.Button("Build Zone"))
            {
                HandleBuildRequest(false);
            }

            ////////////////////////////////////////////////////////////////////
            GUILayout.Space(MarginSize);

            // Only disable baking if there is nothing at all that can be baked.
            GUI.enabled = guiEnabled && activeCount == 0 && (bakeableCount > 0);

            GUIStyle style = (bakeableCount > 0 && activeCount == 0)
                ? ControlUtil.HighlightedButton : GUI.skin.button;

            if (GUILayout.Button("Bake All", style))
            {
                HandleBake();
            }

            ////////////////////////////////////////////////////////////////////
            GUILayout.Space(MarginSize);

            // Note: Technically only the last condition is needed.  But checking the
            // other conditions first saves processing time.
            GUI.enabled = guiEnabled && activeCount == 0 &&
                          tdata.GetStateCount(TileBuildState.NotBuilt) < tdata.Width * tdata.Depth;

            if (GUILayout.Button((needBaking ? "Revert Unbaked" : "Clear All")))
            {
                HandleClear();
            }

            GUI.enabled = guiEnabled && (activeCount != 0);

            if (GUILayout.Button("Abort Builds"))
            {
                Context.AbortAllReqests("User requested.");
            }

            ////////////////////////////////////////////////////////////////////
            GUILayout.Space(ControlUtil.MarginSize);

            GUI.enabled = guiEnabled;
            if (OnGUIStandardButtons())
            {
                // Special case.  Build was discarded.
                ControlUtil.EndButtonArea();
                return;
            }

            ///////////////////////////////////////////////////////////////////
            GUILayout.Space(MarginSize);

            GUI.enabled = guiEnabled && hasSelection;

            EditorGUIUtility.LookLikeControls(100);
            selection.ZoneSize = EditorGUILayout.IntField("Zone Size", selection.ZoneSize);
            EditorGUIUtility.LookLikeControls();

            GUI.enabled = guiEnabled;

            ////////////////////////////////////////////////////////////////////
            GUILayout.Space(MarginSize);

            GUILayout.Label("Bakeable Tiles: " + bakeableCount);

            ControlUtil.OnGUIStandardButtons(Context, DebugContext, true);

            ControlUtil.EndButtonArea();

            GUI.enabled = origGUIEnabled;
        }