|
|
@@ -13,6 +13,15 @@ using ZIM.Unity;
|
|
|
using o0.Project;
|
|
|
using UnityEngine.SceneManagement;
|
|
|
|
|
|
+public enum ScreenPositioningStep {
|
|
|
+ None, //
|
|
|
+ Start,//开始界面
|
|
|
+ AutoEnd,//自动定位结束后界面
|
|
|
+ Marker,//进行标记界面
|
|
|
+ LightCtrl,//灯光调整界面
|
|
|
+ Successful,//结果选择界面
|
|
|
+}
|
|
|
+
|
|
|
public class LinePosition
|
|
|
{
|
|
|
public int index;
|
|
|
@@ -25,8 +34,7 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
|
|
|
RectTransform canvasRectTransform;
|
|
|
[SerializeField]
|
|
|
RectTransform draggableParent;
|
|
|
- [SerializeField]
|
|
|
- GameObject mask;
|
|
|
+
|
|
|
[SerializeField]
|
|
|
GameObject cameraLight;
|
|
|
[SerializeField]
|
|
|
@@ -51,14 +59,6 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
|
|
|
//相机感光部分
|
|
|
[SerializeField]
|
|
|
Slider slider;
|
|
|
-
|
|
|
- [SerializeField]
|
|
|
- RawImage rawImage;
|
|
|
- [SerializeField]
|
|
|
- RectTransform crosshair;
|
|
|
- [SerializeField]
|
|
|
- RectTransform crosshairSmall;
|
|
|
-
|
|
|
[SerializeField]
|
|
|
GameObject textTip1;
|
|
|
[SerializeField]
|
|
|
@@ -76,15 +76,53 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
|
|
|
[SerializeField] Color normalTextColor = Color.black;
|
|
|
[SerializeField] Color highlightedTextColor = Color.white;
|
|
|
|
|
|
+ [Header("Common Layout Group")]
|
|
|
+ [SerializeField]
|
|
|
+ GameObject mask;
|
|
|
+ [SerializeField]
|
|
|
+ Line maskLine;
|
|
|
+ [SerializeField]
|
|
|
+ RawImage rawImage;
|
|
|
+ [SerializeField]
|
|
|
+ RectTransform crosshair;
|
|
|
+ [Tooltip("存在校准数据时候显示")]
|
|
|
+ [SerializeField] LineGenerator CurrentUILineGenerator;//开始显示屏幕线条
|
|
|
|
|
|
- [SerializeField] TextAutoLanguage2 markerTextAutoLanguage2;
|
|
|
+ [Header("Start Layout Group")]
|
|
|
[SerializeField]
|
|
|
GameObject LayoutStart;
|
|
|
[SerializeField]
|
|
|
+ GameObject StartTextTip1;
|
|
|
+ [SerializeField]
|
|
|
+ GameObject StartTextTipHasData;
|
|
|
+ [Tooltip("没有存在校准数据时候显示")]
|
|
|
+ [SerializeField]
|
|
|
+ GameObject BottomAutoBtn;
|
|
|
+ [Tooltip("存在校准数据时候显示")]
|
|
|
+ [SerializeField]
|
|
|
+ GameObject BottomConfirmBtn;
|
|
|
+
|
|
|
+ [Header("AutoEnd Layout Group")]
|
|
|
+ [SerializeField]
|
|
|
+ GameObject LayoutAutoEnd;
|
|
|
+ [Header("Marker Layout Group")]
|
|
|
+ [SerializeField]
|
|
|
GameObject LayoutMarker;
|
|
|
[SerializeField]
|
|
|
- GameObject LayoutSuccessful;
|
|
|
+ RectTransform crosshairSmall;
|
|
|
+ [Tooltip("标记页面标题提示")]
|
|
|
+ [SerializeField] TextAutoLanguage2 markerTextAutoLanguage2;
|
|
|
|
|
|
+ [Header("LightCtrl Layout Group")]
|
|
|
+ [SerializeField]
|
|
|
+ GameObject LayoutLightCtrl;
|
|
|
+ [SerializeField] Slider sliderContrast;
|
|
|
+ //亮度
|
|
|
+ [SerializeField] Slider sliderBrightness;
|
|
|
+
|
|
|
+ [Header("Successful Layout Group")]
|
|
|
+ [SerializeField]
|
|
|
+ GameObject LayoutSuccessful;
|
|
|
[Tooltip("选择框的Line")]
|
|
|
[SerializeField]
|
|
|
Sprite[] ResultLines;// 0: 选中状态, 1: 未选中状态
|
|
|
@@ -103,49 +141,57 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
|
|
|
[SerializeField] LineGenerator FirstUILineGenerator;//第一个结果屏幕线条
|
|
|
[SerializeField] LineGenerator SecondUILineGenerator;//第二个结果屏幕线条
|
|
|
|
|
|
+
|
|
|
+ //标记当前页面情况
|
|
|
+ ScreenPositioningStep curStepView = ScreenPositioningStep.Start;//设置一个开始页面
|
|
|
+ InfraredDemo infraredDemo;
|
|
|
bool doLocateAuto;
|
|
|
int DefaultResolutionIndex;
|
|
|
private void Awake()
|
|
|
{
|
|
|
+ //设置一次显示相机的image 的颜色
|
|
|
+ rawImage.color = Color.white;
|
|
|
offset = line.MyThickness;
|
|
|
-
|
|
|
}
|
|
|
|
|
|
void Start()
|
|
|
{
|
|
|
+ //获取InfraredDemo
|
|
|
+ infraredDemo = InfraredDemo._ins;
|
|
|
+
|
|
|
doLocateAuto = false;
|
|
|
|
|
|
textTip1.SetActive(true);
|
|
|
//设置btnAuto 高亮
|
|
|
- OnButtonClick(btnAuto);
|
|
|
+ //OnButtonClick(btnAuto);
|
|
|
textTip2.SetActive(false);
|
|
|
|
|
|
//动态设置marker的提示语
|
|
|
- if (BluetoothAim.ins!=null && markerTextAutoLanguage2 != null)
|
|
|
- {
|
|
|
- string name = "";
|
|
|
- bool switchValue = false;
|
|
|
- if (BluetoothAim.ins.isMainConnectToHOUYIPRO())
|
|
|
- {
|
|
|
- name = TextAutoLanguage2.GetTextByKey("TitleTipMarker-HOUYIPro");
|
|
|
- }
|
|
|
- else if (BluetoothAim.ins.isMainConnectToARTEMISPRO())
|
|
|
- {
|
|
|
- name = TextAutoLanguage2.GetTextByKey("TitleTipMarker-ArtemisPro");
|
|
|
- }
|
|
|
- else if (BluetoothAim.ins.isMainConnectToGun())
|
|
|
- {
|
|
|
- //name = TextAutoLanguage2.GetTextByKey("TitleTipMarker-M9");
|
|
|
- switchValue = true;
|
|
|
- }
|
|
|
- if (switchValue)
|
|
|
- {
|
|
|
- markerTextAutoLanguage2.SetTextKey("TitleTipMarker-M9");
|
|
|
- }
|
|
|
- else {
|
|
|
- markerTextAutoLanguage2.textFormatArgs = new object[] { name };
|
|
|
- }
|
|
|
- }
|
|
|
+ //if (BluetoothAim.ins!=null && markerTextAutoLanguage2 != null)
|
|
|
+ //{
|
|
|
+ // string name = "";
|
|
|
+ // bool switchValue = false;
|
|
|
+ // if (BluetoothAim.ins.isMainConnectToHOUYIPRO())
|
|
|
+ // {
|
|
|
+ // name = TextAutoLanguage2.GetTextByKey("TitleTipMarker-HOUYIPro");
|
|
|
+ // }
|
|
|
+ // else if (BluetoothAim.ins.isMainConnectToARTEMISPRO())
|
|
|
+ // {
|
|
|
+ // name = TextAutoLanguage2.GetTextByKey("TitleTipMarker-ArtemisPro");
|
|
|
+ // }
|
|
|
+ // else if (BluetoothAim.ins.isMainConnectToGun())
|
|
|
+ // {
|
|
|
+ // //name = TextAutoLanguage2.GetTextByKey("TitleTipMarker-M9");
|
|
|
+ // switchValue = true;
|
|
|
+ // }
|
|
|
+ // if (switchValue)
|
|
|
+ // {
|
|
|
+ // markerTextAutoLanguage2.SetTextKey("TitleTipMarker-M9");
|
|
|
+ // }
|
|
|
+ // else {
|
|
|
+ // markerTextAutoLanguage2.textFormatArgs = new object[] { name };
|
|
|
+ // }
|
|
|
+ //}
|
|
|
//手动不高亮
|
|
|
//ResetButton(btnHandMovement);
|
|
|
|
|
|
@@ -171,31 +217,52 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
|
|
|
//pos4.anchoredPosition = ScreenLocate.quadUnityVectorList[2].pixelToLocalPosition_AnchorCenter(Vector2.one, canvasRectTransform.rect);
|
|
|
//pos3.anchoredPosition = ScreenLocate.quadUnityVectorList[3].pixelToLocalPosition_AnchorCenter(Vector2.one, canvasRectTransform.rect);
|
|
|
}
|
|
|
-
|
|
|
+ //更新start相关ui
|
|
|
+ UpdateStartUI();
|
|
|
|
|
|
//记录操作的位置信息
|
|
|
oldLinePosition = new List<LinePosition>();
|
|
|
SetLinePos();
|
|
|
|
|
|
//相机感光度
|
|
|
- if (InfraredDemo._ins)
|
|
|
+ if (infraredDemo)
|
|
|
{
|
|
|
- //重置偏移量
|
|
|
- InfraredDemo._ins.ResetCenterOffset();
|
|
|
-
|
|
|
- //重置识别点
|
|
|
- ScreenLocate.Main.ScreenIdentification.ClearQuadCache();
|
|
|
- //清除一下记录的点
|
|
|
- ScreenLocate.quadUnityVectorList.Clear();
|
|
|
+ ////重置偏移量
|
|
|
+ //infraredDemo.ResetCenterOffset();
|
|
|
|
|
|
+ //////重置识别点
|
|
|
+ ////ScreenLocate.Main.ScreenIdentification.ClearQuadCache();
|
|
|
+ //////清除一下记录的点
|
|
|
+ ////ScreenLocate.quadUnityVectorList.Clear();
|
|
|
+ //infraredDemo.ResetPositioningData();
|
|
|
|
|
|
slider.onValueChanged.AddListener((value) =>
|
|
|
{
|
|
|
- InfraredDemo._ins.onSliderEvent(value);
|
|
|
+ infraredDemo.onSliderEvent(value);
|
|
|
});
|
|
|
- InfraredDemo._ins.onSetSliderValue(slider);
|
|
|
+ infraredDemo.onSetSliderValue(slider);
|
|
|
+
|
|
|
+ //对比度
|
|
|
+ sliderContrast.onValueChanged.AddListener((value) =>
|
|
|
+ {
|
|
|
+ infraredDemo.onSliderCustomEvent(value, -20.0f, 20.0f);
|
|
|
+ });
|
|
|
+ infraredDemo.onSetSliderCustomValue(sliderContrast, -20.0f, 20.0f);
|
|
|
+
|
|
|
+ //亮度
|
|
|
+ sliderBrightness.onValueChanged.AddListener((value) =>
|
|
|
+ {
|
|
|
+ infraredDemo.onSliderCustomBrightnessEvent(value, -20.0f, 20.0f);
|
|
|
+ });
|
|
|
+ infraredDemo.onSetSliderCustomBrightnessValue(sliderBrightness, -20.0f, 20.0f);
|
|
|
+
|
|
|
|
|
|
- offset = line.MyThickness = InfraredDemo._ins.lineWidth.Get();
|
|
|
+
|
|
|
+ offset = line.MyThickness = infraredDemo.lineWidth.Get();
|
|
|
+
|
|
|
+
|
|
|
+ ZIM.Unity.QuadrilateralInCamera screen = ScreenLocate.Main.ScreenIdentification.Screen.QuadInCamera;
|
|
|
+ CurrentUILineGenerator.Points = infraredDemo.ConvertQuadToPoints(screen, ScreenLocate.Main.getUVCCameraInfoSize);
|
|
|
|
|
|
}
|
|
|
else {
|
|
|
@@ -226,6 +293,10 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
|
|
|
|
|
|
Debug.Log("PC获取相机的感光度:" + v + " = " + v2);
|
|
|
slider.SetValueWithoutNotify((float)v2);
|
|
|
+
|
|
|
+ // 对 sliderContrast 和 sliderBrightness 调用统一的处理函数
|
|
|
+ HandleSliderValueChanged(sliderContrast, value => ScreenLocate.Main.pcContrast = value, ScreenLocate.Main.pcContrast);
|
|
|
+ HandleSliderValueChanged(sliderBrightness, value => ScreenLocate.Main.pcBrightness = value, ScreenLocate.Main.pcBrightness);
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -240,13 +311,13 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
|
|
|
//}
|
|
|
//slider.onValueChanged.AddListener((value) => {
|
|
|
// //onSliderEvent(value);
|
|
|
- // InfraredDemo._ins.SetBrightness(value);
|
|
|
+ // infraredDemo.SetBrightness(value);
|
|
|
//});
|
|
|
- //slider.value = InfraredDemo._ins.brightness.Get();
|
|
|
+ //slider.value = infraredDemo.brightness.Get();
|
|
|
//修改分辨率。是否清晰一点?
|
|
|
- //DefaultResolutionIndex = InfraredDemo._ins?.ResolutionIndex ?? 0;
|
|
|
+ //DefaultResolutionIndex = infraredDemo?.ResolutionIndex ?? 0;
|
|
|
//Debug.Log("[InfraredScreenPositioningView]开始记录进入时候的分辨率:" + DefaultResolutionIndex);
|
|
|
- //InfraredDemo._ins?.SetResolutionNew(ScreenLocate.Main.HighScreenLocateResolutionIndex);
|
|
|
+ //infraredDemo?.SetResolutionNew(ScreenLocate.Main.HighScreenLocateResolutionIndex);
|
|
|
|
|
|
|
|
|
//if (SB_EventSystem.ins && SB_EventSystem.ins.simulateMouseIsAwaked)
|
|
|
@@ -256,11 +327,28 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
|
|
|
//}
|
|
|
|
|
|
}
|
|
|
-
|
|
|
+ // 两个滑块值处理
|
|
|
+ void HandleSliderValueChanged(UnityEngine.UI.Slider slider, System.Action<float> setValue, float pcValue)
|
|
|
+ {
|
|
|
+ double targetMin2 = -20.0;
|
|
|
+ double targetMax2 = 20.0;
|
|
|
+ double originalMin2 = -1;
|
|
|
+ double originalMax2 = 1;
|
|
|
+ slider.onValueChanged.AddListener((value) =>
|
|
|
+ {
|
|
|
+ double result = InfraredDemo.MapValue(value, targetMin2, targetMax2, originalMin2, originalMax2);
|
|
|
+ Debug.Log($"{slider.name}_current: {value}, result: {result}");
|
|
|
+ setValue((float)result);
|
|
|
+ });
|
|
|
+
|
|
|
+ double mappedValue = InfraredDemo.MapValue(pcValue, originalMin2, originalMax2, targetMin2, targetMax2);
|
|
|
+ Debug.Log($"{slider.name} PC获取相机的感光度: {pcValue} = {mappedValue}");
|
|
|
+ slider.SetValueWithoutNotify((float)mappedValue);
|
|
|
+ }
|
|
|
private void OnDestroy()
|
|
|
{
|
|
|
//修改回进入手动调节页面时候的分辨率
|
|
|
- //InfraredDemo._ins?.SetResolutionNew(DefaultResolutionIndex);
|
|
|
+ //infraredDemo?.SetResolutionNew(DefaultResolutionIndex);
|
|
|
Debug.Log("OnDestroy*********************************AwakenSimulateMouse:" + SB_EventSystem.ins.simulateMouseIsAwaked);
|
|
|
if (SB_EventSystem.ins && !SB_EventSystem.ins.simulateMouseIsAwaked)
|
|
|
{
|
|
|
@@ -316,31 +404,132 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 根据enum操作ui
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="step"></param>
|
|
|
+ public void SetScreenPositioningStepState(ScreenPositioningStep step = ScreenPositioningStep.None)
|
|
|
+ {
|
|
|
+ curStepView = step;
|
|
|
+ AllScreenPositioningStepFalse();
|
|
|
+ switch (step)
|
|
|
+ {
|
|
|
+ case ScreenPositioningStep.Start:
|
|
|
+ mask.SetActive(true);
|
|
|
+ maskLine.SetDrawMask(true);
|
|
|
+ LayoutStart.SetActive(true);
|
|
|
+ UpdateStartUI();
|
|
|
+ break;
|
|
|
+ case ScreenPositioningStep.AutoEnd:
|
|
|
+ mask.SetActive(true);
|
|
|
+ maskLine.SetDrawMask(true);
|
|
|
+ LayoutAutoEnd.SetActive(true);
|
|
|
+ break;
|
|
|
+ case ScreenPositioningStep.Marker:
|
|
|
+ mask.SetActive(true);
|
|
|
+ maskLine.SetDrawMask(true);
|
|
|
+ LayoutMarker.SetActive(true);
|
|
|
+ break;
|
|
|
+ case ScreenPositioningStep.LightCtrl:
|
|
|
+ mask.SetActive(true);
|
|
|
+ maskLine.SetDrawMask(false);
|
|
|
+ LayoutLightCtrl.SetActive(true);
|
|
|
+ break;
|
|
|
+ case ScreenPositioningStep.Successful:
|
|
|
+ mask.SetActive(false);
|
|
|
+ LayoutSuccessful.SetActive(true);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void AllScreenPositioningStepFalse()
|
|
|
+ {
|
|
|
+ LayoutStart.SetActive(false);
|
|
|
+ LayoutMarker.SetActive(false);
|
|
|
+ LayoutAutoEnd.SetActive(false);
|
|
|
+ LayoutLightCtrl.SetActive(false);
|
|
|
+ LayoutSuccessful.SetActive(false);
|
|
|
+ }
|
|
|
+ /// <summary>
|
|
|
+ /// 开始页面时候ui
|
|
|
+ /// </summary>
|
|
|
+ void UpdateStartUI() {
|
|
|
+ if (ScreenLocate.quadUnityVectorList.Count == 0)
|
|
|
+ {
|
|
|
+ //存在数据,显示确认按钮,确认按钮直接跳转到游戏
|
|
|
+ BottomConfirmBtn.SetActive(false);
|
|
|
+ StartTextTip1.SetActive(false);
|
|
|
+ StartTextTipHasData.SetActive(true);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ BottomConfirmBtn.SetActive(true);
|
|
|
+ StartTextTip1.SetActive(true);
|
|
|
+ StartTextTipHasData.SetActive(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public void OnClick_Back()
|
|
|
{
|
|
|
AudioMgr.ins.PlayBtn();
|
|
|
ViewMgr.Instance.DestroyView<InfraredScreenPositioningView>();
|
|
|
}
|
|
|
+ /// <summary>
|
|
|
+ /// 返回最开始页面
|
|
|
+ /// </summary>
|
|
|
+ public void OnClick_BackLayoutStart()
|
|
|
+ {
|
|
|
+ //返回上一步操作
|
|
|
+ infraredDemo.RevokeCenterOffset();
|
|
|
+ SetScreenPositioningStepState(ScreenPositioningStep.Start);
|
|
|
+ }
|
|
|
+ /// <summary>
|
|
|
+ /// 进入环境光测试
|
|
|
+ /// </summary>
|
|
|
+ public void OnClick_EnterLightCtrl() {
|
|
|
+ SetScreenPositioningStepState(ScreenPositioningStep.LightCtrl);
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 进入屏幕标记
|
|
|
/// </summary>
|
|
|
public void OnClick_EnterMarker() {
|
|
|
- LayoutStart.SetActive(false);
|
|
|
- LayoutMarker.SetActive(true);
|
|
|
+ SetScreenPositioningStepState(ScreenPositioningStep.Marker);
|
|
|
}
|
|
|
+ /// <summary>
|
|
|
+ /// 直接进入游戏流程
|
|
|
+ /// </summary>
|
|
|
+ public void OnClick_EnterGame()
|
|
|
+ {
|
|
|
+ //对比确认效果。直接进入游戏引导页面
|
|
|
+ EnterGame();
|
|
|
+ }
|
|
|
+ /// <summary>
|
|
|
+ /// 进入自动流程校准操作
|
|
|
+ /// </summary>
|
|
|
+ public void OnClick_EnterAuto()
|
|
|
+ {
|
|
|
+ //自动按钮时候进入之前的校准流程
|
|
|
+ //重置偏移量
|
|
|
+ infraredDemo.ResetCenterOffset();
|
|
|
+ infraredDemo.ResetPositioningData();
|
|
|
|
|
|
+ OnClick_Auto();
|
|
|
+ }
|
|
|
/// <summary>
|
|
|
/// 自动识别
|
|
|
/// </summary>
|
|
|
public void OnClick_Auto()
|
|
|
{
|
|
|
+
|
|
|
bAuto = true;
|
|
|
doLocateAuto = true;
|
|
|
|
|
|
- textTip1.SetActive(false);
|
|
|
- textTip2.SetActive(true);
|
|
|
+ //textTip1.SetActive(false);
|
|
|
+ //textTip2.SetActive(true);
|
|
|
|
|
|
- ResetButton(btnAuto);
|
|
|
+ //ResetButton(btnAuto);
|
|
|
|
|
|
if (enterFromZimWebCamera)
|
|
|
{
|
|
|
@@ -376,119 +565,51 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
|
|
|
/// </summary>
|
|
|
public void SyncScreenPosition()
|
|
|
{
|
|
|
- //Debug.Log("quadUnityVectorList[i]:" + quadUnityVectorList[i]);
|
|
|
Vector2 texSize = ScreenLocate.Main.getUVCCameraInfoSize;
|
|
|
Debug.Log("texSize:" + texSize + " = " + canvasRectTransform.rect);
|
|
|
- //自动识别时候四个点
|
|
|
- //pos1.anchoredPosition = ScreenLocate.quadUnityVectorList[0].pixelToLocalPosition_AnchorCenter(Vector2.one, canvasRectTransform.rect);
|
|
|
- //pos2.anchoredPosition = ScreenLocate.quadUnityVectorList[1].pixelToLocalPosition_AnchorCenter(Vector2.one, canvasRectTransform.rect);
|
|
|
- //pos4.anchoredPosition = ScreenLocate.quadUnityVectorList[2].pixelToLocalPosition_AnchorCenter(Vector2.one, canvasRectTransform.rect);
|
|
|
- //pos3.anchoredPosition = ScreenLocate.quadUnityVectorList[3].pixelToLocalPosition_AnchorCenter(Vector2.one, canvasRectTransform.rect);
|
|
|
SyncQuadUnityVectorListToPos();
|
|
|
-
|
|
|
SetRectanglePoints(linePosConversion(pos1.localPosition, pos2.localPosition, pos3.localPosition, pos4.localPosition));
|
|
|
+ if (curStepView == ScreenPositioningStep.Start || curStepView == ScreenPositioningStep.AutoEnd) {
|
|
|
+ //如果是开始页面进行自动定位的
|
|
|
+ if(curStepView != ScreenPositioningStep.AutoEnd) SetScreenPositioningStepState(ScreenPositioningStep.AutoEnd);
|
|
|
|
|
|
- //自动识别后隐藏手动按钮
|
|
|
- draggableParent.gameObject.SetActive(false);
|
|
|
- pointsParent.gameObject.SetActive(true);
|
|
|
- if (ScreenLocate.Main) {
|
|
|
- ZIM.Unity.QuadrilateralInCamera screen = ScreenLocate.Main.ScreenIdentification.Screen.QuadInCamera;
|
|
|
- //设置points点
|
|
|
- for (int i = 0; i < 4; i++)
|
|
|
+ QuadrilateralInCamera screenAuto = ScreenLocate.Main.ScreenIdentification.QuadAuto;
|
|
|
+ if (screenAuto != null)
|
|
|
{
|
|
|
- RectTransform t = pointsParent.GetChild(i) as RectTransform;
|
|
|
- t.anchoredPosition = screen.Quad[i].pixelToLocalPosition_AnchorCenter(screen.CameraSize, pointsParent.rect);
|
|
|
+ Debug.Log("[校准流程] AutoEnd 自动识别screenAuto信息 ------------ ");
|
|
|
+ CurrentUILineGenerator.Points = infraredDemo.ConvertQuadToPoints(screenAuto, texSize);
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- //显示最后结果
|
|
|
- LayoutMarker.SetActive(false);
|
|
|
- LayoutSuccessful.SetActive(true);
|
|
|
-
|
|
|
- //设置两个线段
|
|
|
- QuadrilateralInCamera screenAuto = ScreenLocate.Main.ScreenIdentification.QuadAuto;
|
|
|
- QuadrilateralInCamera screenSemiAuto = ScreenLocate.Main.ScreenIdentification.QuadSemiAuto;
|
|
|
-
|
|
|
- var lo = new Vector2(-0.5f, -0.5f);
|
|
|
- if (screenAuto != null)
|
|
|
- {
|
|
|
- Debug.Log("[校准流程]自动识别screenAuto信息 ------------ ");
|
|
|
- FirstUILineGenerator.Points = new Vector2[4] {
|
|
|
- 2 * (new Vector2(screenAuto.Quad[0].x/texSize.x,screenAuto.Quad[0].y/texSize.y) + lo),
|
|
|
- 2 * (new Vector2(screenAuto.Quad[1].x/texSize.x,screenAuto.Quad[1].y/texSize.y) + lo),
|
|
|
- 2 * (new Vector2(screenAuto.Quad[3].x/texSize.x,screenAuto.Quad[3].y/texSize.y) + lo),
|
|
|
- 2 * (new Vector2(screenAuto.Quad[2].x/texSize.x,screenAuto.Quad[2].y/texSize.y) + lo) };
|
|
|
-
|
|
|
- // 打印 Points 的值,合并为一个字符串
|
|
|
- string pointsOutput = "1 Points: ";
|
|
|
- for (int i = 0; i < FirstUILineGenerator.Points.Length; i++)
|
|
|
+ else
|
|
|
{
|
|
|
- pointsOutput += "[" + FirstUILineGenerator.Points[i].x + ", " + FirstUILineGenerator.Points[i].y + "]";
|
|
|
- if (i < FirstUILineGenerator.Points.Length - 1)
|
|
|
- {
|
|
|
- pointsOutput += ", "; // 添加逗号分隔符,最后一个元素后不加
|
|
|
- }
|
|
|
+ Debug.LogError("screenAuto 不存在!");
|
|
|
}
|
|
|
- Debug.Log(pointsOutput);
|
|
|
|
|
|
- // 打印 Quad 的值,合并为一个字符串
|
|
|
- int[] customOrder = new int[] { 0, 1, 3, 2 };
|
|
|
- string quadOutput = "1 Quad Points: ";
|
|
|
- for (int i = 0; i < customOrder.Length; i++)
|
|
|
+ }
|
|
|
+ else if (curStepView == ScreenPositioningStep.Marker) {
|
|
|
+ //显示最后结果
|
|
|
+ SetScreenPositioningStepState(ScreenPositioningStep.Successful);
|
|
|
+ //设置两个线段
|
|
|
+ QuadrilateralInCamera screenAuto = ScreenLocate.Main.ScreenIdentification.QuadAuto;
|
|
|
+ QuadrilateralInCamera screenSemiAuto = ScreenLocate.Main.ScreenIdentification.QuadSemiAuto;
|
|
|
+ if (screenAuto != null)
|
|
|
{
|
|
|
- quadOutput += "[" + screenAuto.Quad[customOrder[i]].x + ", " + screenAuto.Quad[customOrder[i]].y + "]";
|
|
|
- if (i < customOrder.Length - 1)
|
|
|
- {
|
|
|
- quadOutput += ", "; // 添加逗号分隔符,最后一个元素后不加
|
|
|
- }
|
|
|
+ Debug.Log("[校准流程]Successful自动识别screenAuto信息 ------------ ");
|
|
|
+ FirstUILineGenerator.Points = infraredDemo.ConvertQuadToPoints(screenAuto, texSize);
|
|
|
}
|
|
|
- Debug.Log(quadOutput);
|
|
|
-
|
|
|
- }
|
|
|
- else {
|
|
|
- Debug.LogError("screenAuto 不存在!");
|
|
|
- }
|
|
|
- if (screenSemiAuto != null)
|
|
|
- {
|
|
|
- Debug.Log("[校准流程]半自动识别screenSemiAuto信息 ------------ ");
|
|
|
- SecondUILineGenerator.Points = new Vector2[4] {
|
|
|
- 2 * (new Vector2(screenSemiAuto.Quad[0].x/texSize.x,screenSemiAuto.Quad[0].y/texSize.y) + lo),
|
|
|
- 2 * (new Vector2(screenSemiAuto.Quad[1].x/texSize.x,screenSemiAuto.Quad[1].y/texSize.y) + lo),
|
|
|
- 2 * (new Vector2(screenSemiAuto.Quad[3].x/texSize.x,screenSemiAuto.Quad[3].y/texSize.y) + lo),
|
|
|
- 2 * (new Vector2(screenSemiAuto.Quad[2].x/texSize.x,screenSemiAuto.Quad[2].y/texSize.y) + lo) };
|
|
|
-
|
|
|
- // 打印 Points 的值,合并为一个字符串
|
|
|
- string pointsOutput = "2 Points: ";
|
|
|
- for (int i = 0; i < SecondUILineGenerator.Points.Length; i++)
|
|
|
+ else
|
|
|
{
|
|
|
- pointsOutput += "[" + SecondUILineGenerator.Points[i].x + ", " + SecondUILineGenerator.Points[i].y + "]";
|
|
|
- if (i < SecondUILineGenerator.Points.Length - 1)
|
|
|
- {
|
|
|
- pointsOutput += ", "; // 添加逗号分隔符,最后一个元素后不加
|
|
|
- }
|
|
|
+ Debug.LogError("screenAuto 不存在!");
|
|
|
}
|
|
|
- Debug.Log(pointsOutput);
|
|
|
-
|
|
|
- // 打印 Quad 的值,合并为一个字符串
|
|
|
- int[] customOrder = new int[] { 0, 1, 3, 2 };
|
|
|
- string quadOutput = "2 Quad Points: ";
|
|
|
- for (int i = 0; i < customOrder.Length; i++)
|
|
|
+ if (screenSemiAuto != null)
|
|
|
{
|
|
|
- quadOutput += "[" + screenSemiAuto.Quad[customOrder[i]].x + ", " + screenSemiAuto.Quad[customOrder[i]].y + "]";
|
|
|
- if (i < customOrder.Length - 1)
|
|
|
- {
|
|
|
- quadOutput += ", "; // 添加逗号分隔符,最后一个元素后不加
|
|
|
- }
|
|
|
+ Debug.Log("[校准流程]Successful半自动识别screenSemiAuto信息 ------------ ");
|
|
|
+ SecondUILineGenerator.Points = infraredDemo.ConvertQuadToPoints(screenSemiAuto, texSize);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogError("screenSemiAuto 不存在!");
|
|
|
}
|
|
|
- Debug.Log(quadOutput);
|
|
|
-
|
|
|
- }
|
|
|
- else {
|
|
|
- Debug.LogError("screenSemiAuto 不存在!");
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
|
|
|
#region 绘制线段部分
|
|
|
@@ -645,7 +766,7 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
|
|
|
if (!enterFromInfraredDemo)
|
|
|
{
|
|
|
//每次初始化重置一下引导
|
|
|
- InfraredDemo._ins.resetInfraredPlayerPrefs();
|
|
|
+ infraredDemo.resetInfraredPlayerPrefs();
|
|
|
//GameObject connectGuidanceView = ViewManager2.getGameObjectAndShowView(ViewManager2.Path_ConnectGuidanceView);
|
|
|
//connectGuidanceView.GetComponent<ConnectGuidanceView>().showTextipInfrared();
|
|
|
|
|
|
@@ -1088,6 +1209,12 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
|
|
|
ViewManager2.HideView(ViewManager2.Path_InfraredScreenPositioningView);
|
|
|
return;
|
|
|
}
|
|
|
+ EnterGame();
|
|
|
+ //存储一次节点
|
|
|
+ SaveLocalPos();
|
|
|
+ }
|
|
|
+
|
|
|
+ void EnterGame() {
|
|
|
if (InfraredDemo.running)
|
|
|
{
|
|
|
//跳转入界面
|
|
|
@@ -1096,7 +1223,7 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
|
|
|
if (!enterFromInfraredDemo)
|
|
|
{
|
|
|
//每次初始化重置一下引导
|
|
|
- InfraredDemo._ins.resetInfraredPlayerPrefs();
|
|
|
+ infraredDemo.resetInfraredPlayerPrefs();
|
|
|
//GameObject connectGuidanceView = ViewManager2.getGameObjectAndShowView(ViewManager2.Path_ConnectGuidanceView);
|
|
|
//connectGuidanceView.GetComponent<ConnectGuidanceView>().showTextipInfrared();
|
|
|
|
|
|
@@ -1113,8 +1240,6 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
|
|
|
}
|
|
|
|
|
|
}
|
|
|
- //存储一次节点
|
|
|
- SaveLocalPos();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -1124,7 +1249,7 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
|
|
|
|
|
|
ScreenLocate.Main.UpdateQuadUnityVectorList();
|
|
|
SyncQuadUnityVectorListToPos();
|
|
|
- InfraredDemo._ins?.SetLocatePointsToCameraRender(ScreenLocate.quadUnityVectorList, 1, 1);
|
|
|
+ infraredDemo?.SetLocatePointsToCameraRender(ScreenLocate.quadUnityVectorList, 1, 1);
|
|
|
_locatePointList.Clear();
|
|
|
|
|
|
}
|
|
|
@@ -1154,4 +1279,217 @@ public class InfraredScreenPositioningView : JCUnityLib.ViewBase
|
|
|
//}
|
|
|
|
|
|
#endregion
|
|
|
+
|
|
|
+
|
|
|
+ #region 判断点是否在 quad 内部
|
|
|
+ //判断maskline
|
|
|
+ public bool IsPointInMaskLine(Vector2 point) {
|
|
|
+ return IsPointInQuad(point, maskLine.ScreenPositions);
|
|
|
+ }
|
|
|
+ //实现基于射线法,通过数交点的奇偶性来判断点是否在多边形内
|
|
|
+ bool IsPointInQuad(Vector2 point, List<Vector2> quadVertices)
|
|
|
+ {
|
|
|
+ if (quadVertices.Count != 4)
|
|
|
+ {
|
|
|
+ Debug.LogError("Quad must have exactly 4 vertices.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ bool isInside = false;
|
|
|
+ int vertexCount = quadVertices.Count;
|
|
|
+
|
|
|
+ for (int i = 0, j = vertexCount - 1; i < vertexCount; j = i++)
|
|
|
+ {
|
|
|
+ Vector2 vi = quadVertices[i];
|
|
|
+ Vector2 vj = quadVertices[j];
|
|
|
+
|
|
|
+ // 检查射线是否与边相交
|
|
|
+ if (((vi.y > point.y) != (vj.y > point.y)) &&
|
|
|
+ (point.x < (vj.x - vi.x) * (point.y - vi.y) / (vj.y - vi.y) + vi.x))
|
|
|
+ {
|
|
|
+ isInside = !isInside;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return isInside;
|
|
|
+ }
|
|
|
+ /// <summary>
|
|
|
+ /// 判断四个点是否能够形成有效的四边形,并根据面积阈值过滤小四边形
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="points">四个点</param>
|
|
|
+ /// <param name="minArea">面积阈值,用于过滤面积太小的四边形</param>
|
|
|
+ /// <returns>是否是有效的四边形</returns>
|
|
|
+ public bool IsValidQuadrilateral(Vector2[] points, float minArea = 100000.0f)
|
|
|
+ {
|
|
|
+ if (points.Length != 4)
|
|
|
+ {
|
|
|
+ Debug.Log("四个点数不足,无法形成四边形。");
|
|
|
+ return false; // 如果点数不是4,直接返回false
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算四边形的面积
|
|
|
+ float area = CalculateArea(points);
|
|
|
+ Debug.Log($"四边形面积: {area}");
|
|
|
+ if (area < minArea)
|
|
|
+ {
|
|
|
+ Debug.Log($"面积小于阈值: {minArea},返回 false。");
|
|
|
+ return false; // 面积太小,返回 false
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查是否有三点共线
|
|
|
+ for (int i = 0; i < points.Length; i++)
|
|
|
+ {
|
|
|
+ Vector2 a = points[i];
|
|
|
+ Vector2 b = points[(i + 1) % points.Length];
|
|
|
+ Vector2 c = points[(i + 2) % points.Length];
|
|
|
+ if (ArePointsCollinear(a, b, c))
|
|
|
+ {
|
|
|
+ Debug.Log($"点 {a}, {b}, {c} 共线,返回 false。");
|
|
|
+ return false; // 存在共线点,返回 false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查是否为矩形或接近矩形
|
|
|
+ if (!IsRectangle(points))
|
|
|
+ {
|
|
|
+ // 如果不是矩形,检查是否是梯形
|
|
|
+ if (!IsTrapezoid(points))
|
|
|
+ {
|
|
|
+ Debug.Log("既不是矩形,也不是梯形,返回 false。");
|
|
|
+ return false; // 不是矩形也不是梯形,返回 false
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.Log("是梯形。");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.Log("是矩形。");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查对角线是否相交
|
|
|
+ if (DoLinesIntersect(points[0], points[1], points[2], points[3]) ||
|
|
|
+ DoLinesIntersect(points[1], points[2], points[3], points[0]))
|
|
|
+ {
|
|
|
+ Debug.Log("对角线相交,返回 false。");
|
|
|
+ return false; // 对角线相交,返回 false
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查点的排列顺序,确保是顺时针或逆时针
|
|
|
+ if (!ArePointsClockwise(points) && !ArePointsClockwise(points.Reverse().ToArray()))
|
|
|
+ {
|
|
|
+ Debug.Log("点的排列顺序不正确,返回 false。");
|
|
|
+ return false; // 点的排列顺序不正确
|
|
|
+ }
|
|
|
+
|
|
|
+ Debug.Log("四边形有效,返回 true。");
|
|
|
+ return true; // 通过所有检查,返回 true
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 判断是否是矩形(近似90度角)
|
|
|
+ /// </summary>
|
|
|
+ private bool IsRectangle(Vector2[] points)
|
|
|
+ {
|
|
|
+ // 角度容差范围,允许夹角有小的偏差
|
|
|
+ const float dotProductThreshold = 0.1f;
|
|
|
+
|
|
|
+ for (int i = 0; i < points.Length; i++)
|
|
|
+ {
|
|
|
+ Vector2 a = points[i];
|
|
|
+ Vector2 b = points[(i + 1) % points.Length];
|
|
|
+ Vector2 c = points[(i + 2) % points.Length];
|
|
|
+
|
|
|
+ // 计算向量 AB 和 BC 的内积
|
|
|
+ Vector2 ab = b - a;
|
|
|
+ Vector2 bc = c - b;
|
|
|
+ float dotProduct = Vector2.Dot(ab.normalized, bc.normalized);
|
|
|
+
|
|
|
+ // 如果内积接近 0,表示夹角接近 90 度
|
|
|
+ if (Mathf.Abs(dotProduct) > dotProductThreshold)
|
|
|
+ {
|
|
|
+ Debug.Log($"点 {a}, {b}, {c} 的夹角不接近 90 度,返回 false。");
|
|
|
+ return false; // 角度不接近 90 度
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 判断是否是梯形
|
|
|
+ /// </summary>
|
|
|
+ private bool IsTrapezoid(Vector2[] points)
|
|
|
+ {
|
|
|
+ // 斜率容差范围,允许斜率差异较小
|
|
|
+ const float slopeThreshold = 0.2f;
|
|
|
+
|
|
|
+ // 计算对角线的斜率
|
|
|
+ float slope1 = (points[1].y - points[0].y) / (points[1].x - points[0].x);
|
|
|
+ float slope2 = (points[3].y - points[2].y) / (points[3].x - points[2].x);
|
|
|
+
|
|
|
+ // 如果对角线斜率差异小于容差范围,则认为是梯形
|
|
|
+ if (Mathf.Abs(slope1 - slope2) < slopeThreshold)
|
|
|
+ {
|
|
|
+ Debug.Log("对角线平行,判断为梯形。");
|
|
|
+ return true; // 对角线平行,返回 true
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.Log($"对角线斜率差异过大: {slope1} vs {slope2},不是梯形,返回 false。");
|
|
|
+ return false; // 斜率差异过大,不是梯形
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //计算四边形面积
|
|
|
+ float CalculateArea(Vector2[] points)
|
|
|
+ {
|
|
|
+ float area = 0f;
|
|
|
+ int n = points.Length;
|
|
|
+ for (int i = 0; i < n; i++)
|
|
|
+ {
|
|
|
+ Vector2 current = points[i];
|
|
|
+ Vector2 next = points[(i + 1) % n];
|
|
|
+ area += current.x * next.y - current.y * next.x;
|
|
|
+ }
|
|
|
+ return Mathf.Abs(area) / 2f;
|
|
|
+ }
|
|
|
+ //确保点不共线
|
|
|
+ //判断点是否在同一条直线上(即共线),如果共线则无法形成四边形。可以通过计算任意三点的面积是否为 0 来验证是否共线:
|
|
|
+ bool ArePointsCollinear(Vector2 a, Vector2 b, Vector2 c)
|
|
|
+ {
|
|
|
+ float area = Mathf.Abs(a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y)) / 2.0f;
|
|
|
+ return Mathf.Approximately(area, 0f);
|
|
|
+ }
|
|
|
+ //确保边不相交
|
|
|
+ bool DoLinesIntersect(Vector2 a, Vector2 b, Vector2 c, Vector2 d)
|
|
|
+ {
|
|
|
+ float cross(Vector2 p1, Vector2 p2, Vector2 p3)
|
|
|
+ {
|
|
|
+ return (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x);
|
|
|
+ }
|
|
|
+
|
|
|
+ float d1 = cross(a, b, c);
|
|
|
+ float d2 = cross(a, b, d);
|
|
|
+ float d3 = cross(c, d, a);
|
|
|
+ float d4 = cross(c, d, b);
|
|
|
+
|
|
|
+ return d1 * d2 < 0 && d3 * d4 < 0;
|
|
|
+ }
|
|
|
+ //顺时针或逆时针排列顶点
|
|
|
+ bool ArePointsClockwise(Vector2[] points)
|
|
|
+ {
|
|
|
+ float sum = 0;
|
|
|
+ for (int i = 0; i < points.Length; i++)
|
|
|
+ {
|
|
|
+ Vector2 current = points[i];
|
|
|
+ Vector2 next = points[(i + 1) % points.Length];
|
|
|
+ sum += (next.x - current.x) * (next.y + current.y);
|
|
|
+ }
|
|
|
+ return sum < 0; // 小于0为顺时针,大于0为逆时针
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
}
|