public bool Load(string track, string layout = "") { string assistLocation; string acLocation = Environment.GetEnvironmentVariable("AC_ROOT"); if (acLocation == null) { acLocation = AcRootFinder.TryToFind(); } Console.WriteLine("Found AC : {0}", acLocation); if (layout == "") { assistLocation = string.Format(@"{0}\content\tracks\{1}\ai\fast_lane.ai", acLocation, track); } else { assistLocation = string.Format(@"{0}\content\tracks\{1}\{2}\ai\fast_lane.ai", acLocation, track, layout); } aiSpline = AiSpline.FromFile(assistLocation); if (layout == "") { assistLocation = string.Format(@"{0}\content\tracks\{1}\ai\pit_lane.ai", acLocation, track); } else { assistLocation = string.Format(@"{0}\content\tracks\{1}\{2}\ai\pit_lane.ai", acLocation, track, layout); } aiSplinePits = AiSpline.FromFile(assistLocation); Console.WriteLine("Loaded AI Line. N points = {0}.", aiSpline.Points.Length); return(true); }
public static IRenderableObject Create([NotNull] AiSpline aiSpline, float?fixedWidth) { // Four vertices per sector const int verticesPerSector = 4; // Actually, I think it’s 65535, but let’s not go there const int maxVertices = 30000; var aiPoints = aiSpline.Points; var aiPointsExtra = aiSpline.PointsExtra; var sectorsNumber = aiPoints.Length - 1; if (sectorsNumber < 1) { return(new InvisibleObject()); } if (sectorsNumber * verticesPerSector <= maxVertices) { return(Create(aiPoints, aiPointsExtra, fixedWidth, 0, aiPoints.Length)); } var pointsPerObject = maxVertices / verticesPerSector + 1; var result = new RenderableList(); for (var i = 0; i < aiPoints.Length; i += pointsPerObject) { result.Add(Create(aiPoints, aiPointsExtra, fixedWidth, i, Math.Min(i + pointsPerObject, aiPoints.Length))); } AcToolsLogging.Write("Objects: " + result.Count); return(result); }
private static async Task RunInner(TrackObjectBase track, bool aiLane) { string modelsFilename = null, kn5Filename = null, aiLaneFilename = null; if (!aiLane) { modelsFilename = track.ModelsFilename; if (!File.Exists(modelsFilename)) { modelsFilename = null; kn5Filename = Path.Combine(track.Location, track.Id + ".kn5"); if (!File.Exists(kn5Filename)) { ModernDialog.ShowMessage("Model not found"); return; } } } else { aiLaneFilename = track.AiLaneFastFilename; if (!File.Exists(aiLaneFilename)) { ModernDialog.ShowMessage("AI lane not found"); return; } } await PrepareAsync(); TrackMapPreparationRenderer renderer = null; try { using (WaitingDialog.Create("Loading model…")) { renderer = aiLaneFilename == null ? modelsFilename == null ? new TrackMapPreparationRenderer(await Task.Run(() => Kn5.FromFile(kn5Filename))) : new TrackMapPreparationRenderer(await Task.Run(() => TrackComplexModelDescription.CreateLoaded(modelsFilename))) : new TrackMapPreparationRenderer(await Task.Run(() => AiSpline.FromFile(aiLaneFilename))); } var wrapper = new TrackMapRendererWrapper(track, renderer); wrapper.Form.Icon = AppIconService.GetAppIcon(); wrapper.Run(); } catch (Exception e) { NonfatalError.Notify("Can’t update map", e); } finally { renderer?.Dispose(); } }
// default error is 8‰ private void TestTrack(string path, float length, float minWidth, float maxWidth, float lengthError = 0.008f, float widthError = 0.1f) { var f = Path.Combine(AcRoot, path); var ai = AiSpline.FromFile(f); Assert.AreEqual(length, ai.CalculateLength(), length * lengthError, "Length is wrong"); var w = ai.CalculateWidth(); if (w.Item1 == 0f) { // obsolete format? return; } Assert.AreEqual(minWidth, w.Item1, minWidth * widthError, "Min width is wrong"); Assert.AreEqual(maxWidth, w.Item2, maxWidth * widthError, "Max width is wrong"); }
public TrackMapPreparationRenderer(AiSpline kn5) : base(kn5) { Camera = new CameraOrtho(); }