From 343168d85a8726c2c74a4aceaeb1903991a93f54 Mon Sep 17 00:00:00 2001 From: Boki Date: Sun, 15 Feb 2026 11:41:25 -0500 Subject: [PATCH] fixes --- src/Poe2Trade.Navigation/MinimapCapture.cs | 9 +++- src/Poe2Trade.Navigation/WorldMap.cs | 55 ++++++++++++++++++---- 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/Poe2Trade.Navigation/MinimapCapture.cs b/src/Poe2Trade.Navigation/MinimapCapture.cs index 97ec652..1ac80d6 100644 --- a/src/Poe2Trade.Navigation/MinimapCapture.cs +++ b/src/Poe2Trade.Navigation/MinimapCapture.cs @@ -38,8 +38,13 @@ public class MinimapCapture : IFrameConsumer, IDisposable if (detected != _detectedMode) { var oldMode = _detectedMode; + var oldRegion = _detectedMode == MinimapMode.Overlay ? _config.OverlayRegion : _config.CornerRegion; _detectedMode = detected; - Log.Information("MODE SWITCH: {Old} → {New}", oldMode, _detectedMode); + var newRegion = _detectedMode == MinimapMode.Overlay ? _config.OverlayRegion : _config.CornerRegion; + Log.Information("MODE SWITCH: {Old} → {New} | oldRegion=({OX},{OY},{OW}x{OH}) newRegion=({NX},{NY},{NW}x{NH})", + oldMode, _detectedMode, + oldRegion.X, oldRegion.Y, oldRegion.Width, oldRegion.Height, + newRegion.X, newRegion.Y, newRegion.Width, newRegion.Height); ResetAdaptation(); ModeChanged?.Invoke(_detectedMode); } @@ -56,7 +61,7 @@ public class MinimapCapture : IFrameConsumer, IDisposable var frame = ProcessBgr(bgr); if (frame == null) return; - Log.Debug("Process: mode={Mode} cropSize={W}x{H} classifiedSize={CW}x{CH} wallSize={WW}x{WH}", + Log.Information("Process: mode={Mode} cropSize={W}x{H} classifiedSize={CW}x{CH} wallSize={WW}x{WH}", _detectedMode, bgr.Width, bgr.Height, frame.ClassifiedMat.Width, frame.ClassifiedMat.Height, frame.WallMask.Width, frame.WallMask.Height); diff --git a/src/Poe2Trade.Navigation/WorldMap.cs b/src/Poe2Trade.Navigation/WorldMap.cs index 7d9018f..3e5c4a8 100644 --- a/src/Poe2Trade.Navigation/WorldMap.cs +++ b/src/Poe2Trade.Navigation/WorldMap.cs @@ -85,8 +85,8 @@ public class WorldMap : IDisposable StitchWithConfidence(classifiedMat, _position, boosted: true, mode: mode); if (_consecutiveMatchFails >= 30) { - Log.Information("Re-bootstrap: stitching at current position after {Fails} match failures ({Ms:F1}ms)", - _consecutiveMatchFails, sw.Elapsed.TotalMilliseconds); + Log.Information("Re-bootstrap: mode={Mode} pos=({X:F1},{Y:F1}) frameSize={FS} walls={W} stitch={Ms:F1}ms", + mode, _position.X, _position.Y, classifiedMat.Width, wallCountAfter, sw.Elapsed.TotalMilliseconds); _consecutiveMatchFails = 0; } else @@ -114,13 +114,16 @@ public class WorldMap : IDisposable _consecutiveMatchFails = 0; LastMatchSucceeded = true; + var prevPos = _position; _position = matched; var stitchStart = sw.Elapsed.TotalMilliseconds; StitchWithConfidence(classifiedMat, _position, boosted: false, mode: mode); var stitchMs = sw.Elapsed.TotalMilliseconds - stitchStart; - Log.Information("MatchAndStitch: dedup={Dedup:F1}ms match={Match:F1}ms stitch={Stitch:F1}ms total={Total:F1}ms", - dedupMs, matchMs, stitchMs, sw.Elapsed.TotalMilliseconds); + var posDx = _position.X - prevPos.X; + var posDy = _position.Y - prevPos.Y; + Log.Information("MatchAndStitch: mode={Mode} pos=({X:F1},{Y:F1}) moved=({Dx:F1},{Dy:F1}) dedup={Dedup:F1}ms match={Match:F1}ms stitch={Stitch:F1}ms total={Total:F1}ms", + mode, _position.X, _position.Y, posDx, posDy, dedupMs, matchMs, stitchMs, sw.Elapsed.TotalMilliseconds); return _position; } @@ -525,19 +528,53 @@ public class WorldMap : IDisposable } /// - /// Mode switch: clear frame dedup cache (frame sizes differ between modes) - /// but keep template matching active — no blind bootstrap needed since scales match. + /// Mode switch: halve confidence around current position so old mode's weak walls + /// decay quickly while strong walls provide matching reference for the new mode. + /// No re-bootstrap stitch — let the first match find the correct position. /// public void Rebootstrap() { Log.Information("Rebootstrap: frameCount={N} pos=({X:F1},{Y:F1}) matchFails={Fails} prevWallMask={Size}", _frameCount, _position.X, _position.Y, _consecutiveMatchFails, _prevWallMask != null ? $"{_prevWallMask.Width}x{_prevWallMask.Height}" : "null"); + + // Halve confidence around current position — weak walls get demoted, + // strong walls survive to help the new mode's first match find position + var halfClear = 250; // slightly larger than largest frame half (200) + var cx = (int)Math.Round(_position.X); + var cy = (int)Math.Round(_position.Y); + var x0 = Math.Max(0, cx - halfClear); + var y0 = Math.Max(0, cy - halfClear); + var w = Math.Min(_config.CanvasSize, cx + halfClear) - x0; + var h = Math.Min(_config.CanvasSize, cy + halfClear) - y0; + if (w > 0 && h > 0) + { + var rect = new Rect(x0, y0, w, h); + var confThreshold = (short)_config.ConfidenceThreshold; + + using var confRoi = new Mat(_confidence, rect); + using var canvasRoi = new Mat(_canvas, rect); + + var demoted = 0; + for (var row = 0; row < h; row++) + for (var col = 0; col < w; col++) + { + var conf = confRoi.At(row, col); + if (conf <= 0) continue; + conf = (short)(conf / 2); + confRoi.Set(row, col, conf); + if (conf < confThreshold && canvasRoi.At(row, col) == (byte)MapCell.Wall) + { + canvasRoi.Set(row, col, (byte)MapCell.Explored); + demoted++; + } + } + Log.Information("Rebootstrap: halved confidence in {W}x{H} area, demoted {Demoted} weak walls", w, h, demoted); + } + _prevWallMask?.Dispose(); _prevWallMask = null; - // Force one re-bootstrap stitch so the new mode seeds walls on the canvas. - // This triggers needsBootstrap=true (>= 30), skips dedup, stitches boosted. - _consecutiveMatchFails = 30; + // Don't force re-bootstrap — let the match find the correct position first } public void Dispose()