using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using SmartBowSDK; using InfraredManager; using ZIM; using SLAMUVC; using System; /// /// 红外 + 蓝牙的使用示例脚本 /// public class InfraredDemo : MonoBehaviour { public static InfraredDemo _ins; public static double MapValue(double value, double originalMin, double originalMax, double targetMin, double targetMax) { // 线性插值公式 return targetMin + (value - originalMin) * (targetMax - targetMin) / (originalMax - originalMin); } private void Awake() { _ins = this; } void Start() { InitBluetoothModule(); InitInfraredCamera(); } void Update() { UpdateBluetoothModule(); UpdateBluetoothModule6Axis(); UpdateInfraredCamera(); } #region 红外摄像 public static bool running { get => infraredCameraHelper != null; } public static InfraredCameraHelper infraredCameraHelper { get; set; } [SerializeField] RawImage _cameraRender; [SerializeField] RawImage _imageScreenLocateManual; [SerializeField] List _crosshairsInCamera; [SerializeField] Slider _sliderBrightness; [SerializeField] Slider _sliderContrast; [SerializeField] Slider _sliderShakeFilter; [SerializeField] Button _btnReset; [SerializeField] Button _btnScreenLocateManual; [SerializeField] Button _btnScreenLocateManualAuto; [SerializeField] Dropdown _dropdownResolution; [SerializeField] Text _fpsText; int frames; float lastCheckTime; //屏幕上ui的点 List _screenLocatePoints = new(); //屏幕内的点 List _locatePointList = new(); //public ParamFloatValue brightness = new ParamFloatValue("ic_brightness", 50.0f); // public ParamFloatValue contrast = new ParamFloatValue("ic_contrast", 50.0f); public ParamFloatValue shakeFilterValue = new ParamFloatValue("ic_shakeFilterValue2", 6.0f); public ParamFloatValue resoution = new ParamFloatValue("ic_resoution2", 2); string[] sliderNameArray = new string[]{ "亮度", // "对比度"}; string[] sliderStrArray = new string[]{ "PU_BRIGHTNESS", "PU_CONTRAST"}; UVCManager.CameraInfo currentCameraInfo; void InitInfraredCamera() { //SDK创建 Vector2 saveResolution = GetResolution((int)resoution.Get()); infraredCameraHelper = InfraredCameraHelper.GetInstance(); infraredCameraHelper.Create((int)saveResolution.x, (int)saveResolution.y); //位置更新 infraredCameraHelper.OnPositionUpdate += (Vector2 point) => { Ray ray = Camera.main.ScreenPointToRay(point); Vector3 rayEndPoint = ray.GetPoint(200); Bow.Instance.transform.LookAt(rayEndPoint); }; infraredCameraHelper.OnUVCIsReady += (UVCManager.CameraInfo camera) => { if (currentCameraInfo != null) return; currentCameraInfo = camera; //生成控制摄像机的参数滑条 Debug.Log("初始化摄像机!"); //参数面板 for (int i = 0; i < sliderStrArray.Length; i++) { string typeStr = sliderStrArray[i]; UVCCtrlInfo _UVCCtrlInfo = camera.GetInfo(typeStr); int _curValue = _UVCCtrlInfo.current; //指定默认值 //5、UVC亮度 - 50 //6、UVC对比度 - 50 if (typeStr == "PU_BRIGHTNESS") { _sliderBrightness.minValue = _UVCCtrlInfo.min; _sliderBrightness.maxValue = _UVCCtrlInfo.max; _sliderBrightness.wholeNumbers = true; SetBrightness(typeStr, _curValue); _sliderBrightness.onValueChanged.AddListener((newValue) => { SetBrightness(typeStr, newValue); }); } else if (typeStr == "PU_CONTRAST") { _sliderContrast.minValue = _UVCCtrlInfo.min; _sliderContrast.maxValue = _UVCCtrlInfo.max; _sliderContrast.wholeNumbers = true; SetContrast(typeStr, _curValue); _sliderContrast.onValueChanged.AddListener((newValue) => { SetContrast(typeStr, newValue); }); } } SetShakeFilterValue(shakeFilterValue.Get()); _sliderShakeFilter.onValueChanged.AddListener(SetShakeFilterValue); //功能按钮 _btnReset.onClick.AddListener(OnClick_Reset); _btnScreenLocateManual.onClick.AddListener(OnClick_ScreenLocateManual); _btnScreenLocateManualAuto.onClick.AddListener(OnClick_ScreenLocateAuto); //分辨率修改 _dropdownResolution.onValueChanged.AddListener(v => { SetResolution(v); }); //算法红外阈值 infraredCameraHelper.SetInfraredLocateBrightnessThreshold(0.8f); }; //屏幕变化时候 infraredCameraHelper.OnUVCPosUpdate += (list) => { Debug.Log("OnUVCPosUpdate"); SetLocatePointsToCameraRender(list, 1, 1); }; } void UpdateInfraredCamera() { if (infraredCameraHelper == null) return; if (infraredCameraHelper.GetCameraTexture()) { if (_cameraRender.texture == null || infraredCameraHelper.GetCameraTexture().GetNativeTexturePtr() != _cameraRender.texture.GetNativeTexturePtr()) _cameraRender.texture = infraredCameraHelper.GetCameraTexture(); } //手动定位 if (infraredCameraHelper.IsScreenLocateManualDoing()) { //引导提示 string tipText = "单击屏幕 左下角"; if (_screenLocatePoints.Count == 0) _locatePointList.Clear(); if (_screenLocatePoints.Count == 1) tipText = "单击屏幕 右下角"; if (_screenLocatePoints.Count == 2) tipText = "单击屏幕 右上角"; if (_screenLocatePoints.Count == 3) tipText = "单击屏幕 左上角"; _imageScreenLocateManual.transform.Find("Text").GetComponent().text = tipText; //点击检测 if (Input.GetMouseButtonDown(0)) { Vector2 mouse = Input.mousePosition; float u = Mathf.Clamp01(mouse.x / Screen.width); float v = Mathf.Clamp01(mouse.y / Screen.height); u = Math.Clamp(u, 0, 1); v = Math.Clamp(v, 0, 1); _locatePointList.Add(new Vector2(u, v)); float texWidth = _imageScreenLocateManual.texture.width; float texHeight = _imageScreenLocateManual.texture.height; Vector2 texPoint = new Vector2(u * texWidth, v * texHeight); _screenLocatePoints.Add(texPoint); } //定位点显示 Transform pointsTF = _imageScreenLocateManual.transform.Find("Points"); for (int i = 0; i < pointsTF.childCount; i++) { Transform pointTF = pointsTF.GetChild(i); if (i < _screenLocatePoints.Count) { float texWidth = _imageScreenLocateManual.texture.width; float texHeight = _imageScreenLocateManual.texture.height; Vector2 texSize = new Vector2(texWidth, texHeight); Vector2 pos = _screenLocatePoints[i]; pointTF.localPosition = pos.pixelToLocalPosition_AnchorCenter(texSize, _imageScreenLocateManual.rectTransform.rect); pointTF.gameObject.SetActive(true); } else pointTF.gameObject.SetActive(false); } //完成定位 if (_screenLocatePoints.Count == 4) { _imageScreenLocateManual.gameObject.SetActive(false); SetLocatePointsToCameraRender(_screenLocatePoints, _imageScreenLocateManual.texture.width, _imageScreenLocateManual.texture.height); infraredCameraHelper.QuitScreenLocateManual(_locatePointList); } } //在相机画面显示准心 if (ScreenLocate.Main) { var _sl = ScreenLocate.Main; var buffer = _sl.infraredSpotBuffer; if (buffer != null) { for (int i = 0; i < buffer.Length; i++) { if (buffer[i].CameraLocation != null) { //添加一个偏移量,使得最后输出的准心是指向正中心 Vector2 newPoint2 = _sl.GetOffsetCameraLocation(buffer[i].CameraLocation.Value); // 检测到光点 var pos = newPoint2.pixelToLocalPosition_AnchorCenter(_sl.mUVCCameraInfo.Size, _cameraRender.rectTransform.rect); _crosshairsInCamera[i].gameObject.SetActive(true); _crosshairsInCamera[i].anchoredPosition = pos; } else _crosshairsInCamera[i].gameObject.SetActive(false); } } } //性能检测 ++frames; float timeNow = Time.realtimeSinceStartup; const float UpdateInterval = 0.5f; if (timeNow > lastCheckTime + UpdateInterval) { float fps = (float)(frames / (timeNow - lastCheckTime)); frames = 0; lastCheckTime = timeNow; _fpsText.text = "FPS:" + fps.ToString("f2"); } } public void SetLocatePointsToCameraRender(List points, float w, float h) { Transform pointsTF2 = _cameraRender.transform.Find("Points"); if (pointsTF2.childCount == points.Count) { Vector2 texSize = new Vector2(w, h); for (int i = 0; i < pointsTF2.childCount; i++) { Transform pointTF = pointsTF2.GetChild(i); Vector2 pos = points[i]; pointTF.localPosition = pos.pixelToLocalPosition_AnchorCenter(texSize, _cameraRender.rectTransform.rect); pointTF.gameObject.SetActive(true); } } } /// /// 亮度 /// /// /// void SetBrightness(string typeStr, float v) { var _value = Mathf.FloorToInt(v); currentCameraInfo.SetValue(typeStr, _value); //brightness.Set(v); _sliderBrightness.SetValueWithoutNotify(v); _sliderBrightness.transform.Find("Value").GetComponent().text = v.ToString("f1"); } /// /// 对比度 /// /// /// void SetContrast(string typeStr, float v) { var _value = Mathf.FloorToInt(v); currentCameraInfo.SetValue(typeStr, _value); //contrast.Set(v); _sliderContrast.SetValueWithoutNotify(v); _sliderContrast.transform.Find("Value").GetComponent().text = v.ToString("f1"); } void SetShakeFilterValue(float v) { shakeFilterValue.Set(v); _sliderShakeFilter.SetValueWithoutNotify(shakeFilterValue.Get()); _sliderShakeFilter.transform.Find("Value").GetComponent().text = shakeFilterValue.Get().ToString("f1"); InfraredCameraHelper.GetInstance().SetShakeFilterValue(shakeFilterValue.Get()); } void SetResolution(int optionIndex) { resoution.Set(optionIndex); _dropdownResolution.SetValueWithoutNotify(optionIndex); switch (optionIndex) { case 0: infraredCameraHelper.SetCameraResolutionNew(1280, 720); break; case 1: infraredCameraHelper.SetCameraResolutionNew(640, 360); break; case 2: infraredCameraHelper.SetCameraResolutionNew(320, 240); break; case 3: infraredCameraHelper.SetCameraResolutionNew(160, 120); break; } } Vector2 GetResolution(int optionIndex) { _dropdownResolution.SetValueWithoutNotify(optionIndex); Vector2 vect = new Vector2(320, 240); switch (optionIndex) { case 0: vect = new Vector2(1280, 720); break; case 1: vect = new Vector2(640, 360); break; case 2: vect = new Vector2(320, 240); break; case 3: vect = new Vector2(160, 120); break; } return vect; } void OnClick_Reset() { SetBrightness("PU_BRIGHTNESS", 50); SetContrast("PU_CONTRAST", 50); SetShakeFilterValue(6); } void OnClick_ScreenLocateManual() { if (infraredCameraHelper.IsScreenLocateManualDoing()) return; Texture2D texture2D = infraredCameraHelper.EnterScreenLocateManual(); if (texture2D == null) { infraredCameraHelper.QuitScreenLocateManual(null); return; } _imageScreenLocateManual.texture = texture2D; //_imageScreenLocateManual.material = infraredCameraHelper.GetCameraMaterial(); _screenLocatePoints.Clear(); _imageScreenLocateManual.gameObject.SetActive(true); } void OnClick_ScreenLocateAuto() { infraredCameraHelper.EnterScreenLocateManualAuto(); } public void OnClick_SetAdjustPointsOffset() { var _sl = ScreenLocate.Main; var buffer = _sl.infraredSpotBuffer; if (buffer != null) { for (int i = 0; i < buffer.Length; i++) { if (buffer[i].CameraLocation != null) { Debug.Log("CameraLocation:" + buffer[i].CameraLocation.Value); var centerOffset = infraredCameraHelper.GetCenterOffset(buffer[i].CameraLocation.Value, "CameraLocation"); Debug.Log("CenterOffset: " + centerOffset); var uvCenterOffset = infraredCameraHelper.GetCenterOffset(buffer[i].ScreenUV.Value, "ScreenUV"); Debug.Log("UvCenterOffset: " + uvCenterOffset); } } } } #endregion #region 蓝牙模块 [SerializeField] Button _btnConnect; [SerializeField] Text _textMacAddress; [SerializeField] Text _textBattery; SmartBowHelper OriginSmartBowHelper; //六轴部分按钮操作 [SerializeField] Button _btnConnect6Axis; [SerializeField] Text _textMacAddress6Axis; [SerializeField] Text _textBattery6Axis; SmartBowHelper BGBoxSmartBowHelper; [SerializeField] GameObject _BGBoxObj; void InitBluetoothModule() { SmartBowLogger.isDebug = true; OriginSmartBowHelper = SmartBowHelper.NewInstance(); OriginSmartBowHelper.OnBluetoothModuleInited += OnBluetoothModuleInited; OriginSmartBowHelper.OnBluetoothError += OnBluetoothError; OriginSmartBowHelper.OnShooting += OnShooting; _btnConnect.onClick.AddListener(OnClick_Connect); //6轴部分代码 BGBoxSmartBowHelper = SmartBowHelper.NewInstance(); BGBoxSmartBowHelper.OnBluetoothModuleInited += OnBluetoothModuleInited6Axis; BGBoxSmartBowHelper.OnBluetoothError += OnBluetoothError6Axis; BGBoxSmartBowHelper.OnSixAxisRotationUpdate += (eulerAngles) => { _BGBoxObj.transform.eulerAngles = eulerAngles; }; //识别当前手柄 BGBoxSmartBowHelper.SetFilters("BGBox_202012"); //设置手柄解析 BGBoxSmartBowHelper.SetSensorAxisType(SensorAxisType.SixAxisSensor); _btnConnect6Axis.onClick.AddListener(OnClick_ConnectBGBox); if (BluetoothWindows.IsWindows()) { BleWinHelper.RegisterTo(OriginSmartBowHelper.gameObject, OriginSmartBowHelper.CreateBluetoothWindows()); BleWinHelper.RegisterTo(BGBoxSmartBowHelper.gameObject, BGBoxSmartBowHelper.CreateBluetoothWindows()); } //Debug.Log("InitBluetoothModule"); } void UpdateBluetoothModule() { //更新显示蓝牙状态 BluetoothStatusEnum bluetoothStatus = OriginSmartBowHelper.GetBluetoothStatus(); Text btnConnectText = _btnConnect.GetComponentInChildren(); if (bluetoothStatus == BluetoothStatusEnum.None) btnConnectText.text = "未连接(点击连接)"; if (bluetoothStatus == BluetoothStatusEnum.Connecting) btnConnectText.text = "连接中"; if (bluetoothStatus == BluetoothStatusEnum.Connected) { if (OriginSmartBowHelper.IsBluetoothModuleInited()) btnConnectText.text = "已连接(点击断开)"; else btnConnectText.text = "已连接(正在初始化)"; } //更新显示电量 int battery = OriginSmartBowHelper.GetBattery(); _textBattery.text = battery > 0 ? $"电量值:{battery}" : "未获得电量值"; //更新显示Mac地址 string macAddress = OriginSmartBowHelper.GetMacAddress(); _textMacAddress.text = macAddress != null ? $"Mac地址:{macAddress}" : "未获得Mac地址"; } void OnBluetoothModuleInited() { OriginSmartBowHelper.StartRotationSensor(); OriginSmartBowHelper.StartShootingSensor(); } void OnBluetoothError(BluetoothError error, string message) { Debug.Log("OnBluetoothError:" + error); if (error == BluetoothError.ScanNotFoundTargetDevice) { TipText.Show("连接失败,未发现目标设备!"); return; } TipText.Show(message); } void OnShooting(float speed) { Bow.Instance.Shoot(); } void OnClick_Connect() { if (OriginSmartBowHelper.GetBluetoothStatus() == BluetoothStatusEnum.Connecting) return; if (OriginSmartBowHelper.GetBluetoothStatus() == BluetoothStatusEnum.None) { OriginSmartBowHelper.Connect("test", 1); return; } if (OriginSmartBowHelper.GetBluetoothStatus() == BluetoothStatusEnum.Connected) { OriginSmartBowHelper.Disconnect(); return; } } /// /// 更新BGBox信息 /// void UpdateBluetoothModule6Axis() { //更新显示蓝牙状态 BluetoothStatusEnum bluetoothStatus = BGBoxSmartBowHelper.GetBluetoothStatus(); Text btnConnectText = _btnConnect6Axis.GetComponentInChildren(); if (bluetoothStatus == BluetoothStatusEnum.None) btnConnectText.text = "未连接(点击连接)"; if (bluetoothStatus == BluetoothStatusEnum.Connecting) btnConnectText.text = "连接中"; if (bluetoothStatus == BluetoothStatusEnum.Connected) { if (BGBoxSmartBowHelper.IsBluetoothModuleInited()) btnConnectText.text = "已连接(点击断开)"; else btnConnectText.text = "已连接(正在初始化)"; } //更新显示电量 int battery = BGBoxSmartBowHelper.GetBattery(); _textBattery6Axis.text = battery > 0 ? $"电量值:{battery}" : "未获得电量值"; //更新显示Mac地址 string macAddress = BGBoxSmartBowHelper.GetMacAddress(); _textMacAddress6Axis.text = macAddress != null ? $"Mac地址:{macAddress}" : "未获得Mac地址"; } void OnBluetoothModuleInited6Axis() { BGBoxSmartBowHelper.StartRotationSensor(); } public void Open6Axis() { BGBoxSmartBowHelper.StartRotationSensor(); } public void Close6Axis() { BGBoxSmartBowHelper.StopRotationSensor(); } public void Reset6Axis() { // if(sixAxisFusion!=null) sixAxisFusion.ResetToInitialRotation(); BGBoxSmartBowHelper.ResetSixAxisIdentity(); } void OnBluetoothError6Axis(BluetoothError error, string message) { Debug.Log("6Axis OnBluetoothError:" + error); if (error == BluetoothError.ScanNotFoundTargetDevice) { TipText.Show("连接失败,未发现目标设备!"); return; } TipText.Show(message); } void OnClick_ConnectBGBox() { if (BGBoxSmartBowHelper.GetBluetoothStatus() == BluetoothStatusEnum.Connecting) return; if (BGBoxSmartBowHelper.GetBluetoothStatus() == BluetoothStatusEnum.None) { BGBoxSmartBowHelper.Connect("test2", 1); return; } if (BGBoxSmartBowHelper.GetBluetoothStatus() == BluetoothStatusEnum.Connected) { BGBoxSmartBowHelper.Disconnect(); return; } } #endregion } public class ParamFloatValue { private string _saveKey; private float _valueDefault; private bool _valueLoaded; private float _value; public ParamFloatValue(string saveKey, float valueDefault) { _saveKey = saveKey; _valueDefault = valueDefault; } public float Get() { if (!_valueLoaded) _value = PlayerPrefs.GetFloat(_saveKey, _valueDefault); return _value; } public void Set(float value) { _value = value; PlayerPrefs.SetFloat(_saveKey, _value); PlayerPrefs.Save(); } }