Files
better-genshin-impact/BetterGenshinImpact/GameTask/AutoPathing/Navigation.cs
辉鸭蛋 9e41808326 独立与分层地图支持 (#1503)
* 抽象基础类

* 修改定义

* 抽象出Feature2D相关能力

* 新增地图基类实现

* 临时提交

* 迁移坐标计算

* 加载分层特征数据

* 新增独立地图 层岩巨渊,渊下宫,旧日之海

* 支持不切分特征点匹配

* 添加远古圣山,修改地图参数

* 提瓦特大陆的大地图匹配

* 提瓦特大陆地图大地图位置获取使用256级别的地图

* 替换大地图匹配类 BigMap.cs

* 替换小地图匹配类 EntireMap

* 修改tp的入参方式,删除无用类

* 兼容新提交的内容

* 修复类方法覆盖不生效的问题

* 修复定位问题,迁移部分 MapCoordinate 的代码。MapCoordinate 标记为废弃

* 更多坐标方法的迁移

* 修复不正确的坐标转换

* 是用正确的特征匹配

* 体积较小的地图动态生成特征

* 路径追踪窗体支持多地图

* 传送时切换独立地图地区

* 更新传送点信息

* 修改独立地图相关命名,使用 Scene(场景) 命名,和原神内部命名保持一致

* 录制支持多独立地图

* 修复地区切换失败的问题
2025-05-03 21:59:37 +08:00

117 lines
3.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using BetterGenshinImpact.GameTask.AutoPathing.Model;
using BetterGenshinImpact.GameTask.Common.Map;
using BetterGenshinImpact.GameTask.Model.Area;
using OpenCvSharp;
using System;
using System.Diagnostics;
using BetterGenshinImpact.GameTask.Common;
using BetterGenshinImpact.GameTask.Common.Element.Assets;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
using BetterGenshinImpact.GameTask.Common.Map.Maps;
using BetterGenshinImpact.GameTask.Common.Map.Maps.Base;
namespace BetterGenshinImpact.GameTask.AutoPathing;
public class Navigation
{
private static bool _isWarmUp = false;
private static float _prevX = -1;
private static float _prevY = -1;
public static void WarmUp()
{
if (!_isWarmUp)
{
MapManager.GetMap(MapTypes.Teyvat);
}
_isWarmUp = true;
Reset();
}
public static void Reset()
{
(_prevX, _prevY) = (-1, -1);
}
public static void SetPrevPosition(float x, float y)
{
(_prevX, _prevY) = (x, y);
}
public static Point2f GetPosition(ImageRegion imageRegion, string mapName)
{
var greyMat = new Mat(imageRegion.SrcGreyMat, MapAssets.Instance.MimiMapRect);
var p = MapManager.GetMap(mapName).GetMiniMapPosition(greyMat, _prevX, _prevY);
if (p != default)
{
(_prevX, _prevY) = (p.X, p.Y);
}
WeakReferenceMessenger.Default.Send(new PropertyChangedMessage<object>(typeof(Navigation),
"SendCurrentPosition", new object(), p));
return p;
}
/// <summary>
/// 稳定获取当前位置坐标,优先使用全地图匹配,适用于不需要高效率但需要高稳定性的场景
/// </summary>
/// <param name="imageRegion">图像区域</param>
/// <param name="mapName"></param>
/// <returns>当前位置坐标</returns>
public static Point2f GetPositionStable(ImageRegion imageRegion, string mapName)
{
var greyMat = new Mat(imageRegion.SrcGreyMat, MapAssets.Instance.MimiMapRect);
// 先尝试使用局部匹配
var p = MapManager.GetMap(mapName).GetMiniMapPosition(greyMat, _prevX, _prevY);
// 如果局部匹配失败,再尝试全地图匹配失败
if (p == new Point2f())
{
Reset();
p = MapManager.GetMap(mapName).GetMiniMapPosition(greyMat, _prevX, _prevY);
}
if (p != default)
{
(_prevX, _prevY) = (p.X, p.Y);
}
WeakReferenceMessenger.Default.Send(new PropertyChangedMessage<object>(typeof(Navigation),
"SendCurrentPosition", new object(), p));
return p;
}
public static int GetTargetOrientation(Waypoint waypoint, Point2f position)
{
double deltaX = waypoint.X - position.X;
double deltaY = waypoint.Y - position.Y;
double vectorLength = Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
if (vectorLength == 0)
{
return 0;
}
// 计算向量与x轴之间的夹角逆时针方向
double angle = Math.Acos(deltaX / vectorLength);
// 如果向量在x轴下方角度需要调整
if (deltaY < 0)
{
angle = 2 * Math.PI - angle;
}
return (int)(angle * (180.0 / Math.PI));
}
public static double GetDistance(Waypoint waypoint, Point2f position)
{
var x1 = waypoint.X;
var y1 = waypoint.Y;
var x2 = position.X;
var y2 = position.Y;
return Math.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}
}