private bool AbortRequest(int tx, int tz, string reason) { bool result = false; // This is a thorough check, taking into account potential errors. for (int i = mNMGenTasks.Count - 1; i >= 0; i--) { NMGenTask item = mNMGenTasks[i]; if (item.TileX == tx && item.TileZ == tz) { item.Abort(reason); mNMGenTasks.RemoveAt(i); mBuild.BuildData.ClearUnbaked(tx, tz); result = true; } } for (int i = mTileTasks.Count - 1; i >= 0; i--) { TileBuildTask item = mTileTasks[i]; if (item.TileX == tx && item.TileZ == tz) { item.Abort(reason); mTileTasks.RemoveAt(i); mBuild.BuildData.ClearUnbaked(tx, tz); result = true; } } return(result); }
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); }
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); } } }
public bool QueueTask(int tx, int tz, int priority, BuildContext logger) { // Check for existing task and purge it. NavmeshBuild build = Build; if (!build) { return(false); } TileBuildData tdata = build.BuildData; if (build.TileSetDefinition == null && (tx > 0 || tz > 0)) { logger.LogError("Tile build requested, but no tile set found.", this); return(false); } if (AbortRequest(tx, tz, "Overriden by new task.")) { tdata.ClearUnbaked(tx, tz); logger.LogWarning(string.Format( "Existing build task overridden by new task. ({0}, {1})" , tx, tz), this); } IncrementalBuilder builder; NMGenConfig config = build.Config; if (build.TileSetDefinition == null) { InputGeometry geom = build.InputGeom; if (geom == null) { logger.LogError("Input geometry not available.", this); tdata.SetAsFailed(tx, tz); return(false); } builder = IncrementalBuilder.Create(config.GetConfig() , config.ResultOptions , geom , build.NMGenProcessors); } else { builder = IncrementalBuilder.Create(tx, tz , config.ResultOptions , build.TileSetDefinition , build.NMGenProcessors); } if (builder == null) { logger.LogError(string.Format("Tile set did not produce a builder. Tile: ({0},{1})" , tx, tz) , this); return(false); } NMGenTask task = NMGenTask.Create(builder, priority); if (!mTaskProcessor.QueueTask(task)) { logger.LogError(string.Format("Processor rejected task. Tile: ({0},{1})" , tx, tz), this); return(false); } mNMGenTasks.Add(task); tdata.SetAsQueued(tx, tz); return(true); }