AimHandler.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. using System;
  2. using UnityEngine;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using UnityEngine.UI;
  7. using Newtonsoft.Json;
  8. using o0._9Axis;
  9. using o0;
  10. /* 瞄准处理器 */
  11. public class AimHandler : MonoBehaviour
  12. {
  13. private Quaternion _gameRotation = Quaternion.identity;
  14. private Quaternion gameRotation
  15. {
  16. get
  17. {
  18. return _gameRotation;
  19. }
  20. set
  21. {
  22. _gameRotation = value;
  23. onGameRotationUpdate?.Invoke(Quaternion.LookRotation(_gameRotation * Vector3.forward));
  24. }
  25. }
  26. public Action<Quaternion> onGameRotationUpdate;
  27. long TimeGap = default;
  28. Vector3 Acc = default;
  29. Vector3 Gyr = default;
  30. Vector3 Mag = default;
  31. public o09Axis _9Axis = new o09Axis();
  32. Vector3 cMaxVector = new Vector3(0,0,0);
  33. Vector3 cMinVector = new Vector3(0, 0, 0);
  34. [o0.Serialize]
  35. MagnetometerAutoCalibrater MagCalibrater;
  36. o0GyrCalibrater GyrCalibrater;
  37. //陀螺仪校准进度记录
  38. [NonSerialized] public int gyrCalibrateCompleteCount = 0;
  39. [NonSerialized] public int gyrCalibrateTotalCount = 2000;
  40. [NonSerialized] public long msOld = 0;
  41. public static AimHandler ins;
  42. void Start()
  43. {
  44. ins = this;
  45. _9Axis.LoadIdentity();
  46. InitGyr(null);
  47. InitMag(null);
  48. }
  49. public void InitGyr(string record) {
  50. GyrCalibrater = new o0GyrCalibrater();
  51. try {
  52. if (string.IsNullOrEmpty(record))
  53. {
  54. record = PlayerPrefs.GetString("gyr-calibrate-record");
  55. }
  56. if (!string.IsNullOrEmpty(record)) {
  57. var res = JsonConvert.DeserializeObject<o0GyrCalibrater>(record);
  58. if (res != null) GyrCalibrater = res;
  59. }
  60. } catch(Exception) {}
  61. }
  62. public void InitMag(string record) {
  63. MagCalibrater = new MagnetometerAutoCalibrater();
  64. try {
  65. if (string.IsNullOrEmpty(record))
  66. {
  67. record = PlayerPrefs.GetString("mag-calibrate-record");
  68. }
  69. if (!string.IsNullOrEmpty(record)) {
  70. Json.FromJson<MagnetometerAutoCalibrater>(record, ref MagCalibrater);
  71. }
  72. } catch (System.Exception) {}
  73. magComplete = MagCalibrater.Complete;
  74. }
  75. public void ResetGyr() {
  76. GyrCalibrater._Average = Vector3.zero;
  77. PlayerPrefs.DeleteKey("gyr-calibrate-record");
  78. }
  79. public void ResetMag() {
  80. MagCalibrater = new MagnetometerAutoCalibrater();
  81. PlayerPrefs.DeleteKey("mag-calibrate-record");
  82. }
  83. public bool IsGyrCompleted() {
  84. return !GyrCalibrater._Average.Equals(Vector3.zero);
  85. }
  86. public bool IsMagCompleted() {
  87. return MagCalibrater.Complete;
  88. }
  89. public IEnumerator SaveGyr() {
  90. yield return null;
  91. string record = JsonConvert.SerializeObject(GyrCalibrater);
  92. PlayerPrefs.SetString("gyr-calibrate-record", record);
  93. }
  94. public IEnumerator SaveMag() {
  95. yield return null;
  96. string record = MagCalibrater.ToJson();
  97. PlayerPrefs.SetString("mag-calibrate-record", record);
  98. }
  99. public void CalibrateGyr(bool calibration) {
  100. try {
  101. GyrCalibrater.Calibration = calibration;
  102. } catch (Exception e) { Debug.LogError(e.Message); }
  103. }
  104. //转换读取的数据,无符号->有符号
  105. float TwoByteToFloat(byte b1, byte b2)
  106. {
  107. ushort twoByte = (ushort) (b1 * 256 + b2);
  108. short shortNum = (short) twoByte;
  109. return (float) shortNum;
  110. }
  111. public void OnDataReceived(byte[] bytes)
  112. {
  113. // Debug.Log("瞄准模块数据长度" + bytes.Length);
  114. if (bytes.Length != 27)
  115. {
  116. if (bytes.Length == 2) {
  117. if (bytes[0] == 0x66 && bytes[1] == 0x31) {
  118. //if (SB_EventSystem.ins && SB_EventSystem.ins.simulateMouseIsAwaked) {
  119. //视角回正
  120. DoIdentity();
  121. //鼠标居中自然会居中
  122. //} else {
  123. // AutoResetView.DoIdentity();
  124. //}
  125. } else if (bytes[0] == 0x66 && bytes[1] == 0x32) {
  126. //if (SB_EventSystem.ins) {
  127. // //唤起/隐藏虚拟鼠标
  128. // SB_EventSystem.ins.AwakenSimulateMouse();
  129. //}
  130. } else if (bytes[1] == 10) {
  131. //显示电量
  132. //DeviceBatteryView.ins.RenderBattery(1, bytes[0]);
  133. }
  134. } else if (bytes[0] == 0x5b) {
  135. //红外射击检测
  136. ShootCheck.ins.ShootByInfrared(bytes);
  137. }
  138. return;
  139. }
  140. if (bytes[7] == 0 && bytes[8] == 0 && bytes[9] == 0 && bytes[10] == 0 && bytes[11] == 0 && bytes[12] == 0)
  141. return;
  142. if (bytes[19] == 0 && bytes[20] == 0 && bytes[21] == 0 && bytes[22] == 0 && bytes[23] == 0 && bytes[24] == 0)
  143. return;
  144. float ax = TwoByteToFloat(bytes[7], bytes[8]);
  145. float ay = TwoByteToFloat(bytes[9], bytes[10]);
  146. float az = TwoByteToFloat(bytes[11], bytes[12]);
  147. float roll = TwoByteToFloat(bytes[13], bytes[14]);
  148. float pitch = TwoByteToFloat(bytes[15], bytes[16]);
  149. float yaw = TwoByteToFloat(bytes[17], bytes[18]);
  150. float x = TwoByteToFloat(bytes[19], bytes[20]);
  151. float y = TwoByteToFloat(bytes[21], bytes[22]);
  152. float z = TwoByteToFloat(bytes[23], bytes[24]);
  153. float mxr = TwoByteToFloat(bytes[20], bytes[19]);
  154. float myr = TwoByteToFloat(bytes[22], bytes[21]);
  155. float mzr = TwoByteToFloat(bytes[24], bytes[23]);
  156. if (BluetoothAim.devicePlan == 3)
  157. {
  158. Acc = new Vector3(az, ay, ax) / 32768 * 16;
  159. Gyr = new Vector3(-yaw, -pitch, -roll) / 32768 * 2;
  160. Mag = new Vector3(z, y, -x) / 32768 * 256; //最新版
  161. }
  162. else if (BluetoothAim.devicePlan == 0)
  163. {
  164. Acc = new Vector3(-az, ay, -ax) / 32768 * 16;
  165. Gyr = new Vector3(yaw, -pitch, roll) / 32768 * 2;
  166. Mag = new Vector3(-z, y, x) / 32768 * 256; //旧版
  167. }
  168. else if (BluetoothAim.devicePlan == 1)
  169. {
  170. Acc = new Vector3(ax, ay, az) / 32768 * 16;
  171. Gyr = new Vector3(roll, pitch, yaw) / 32768 * 2;
  172. Mag = new Vector3(z, x, -y) / 32768 * 256;//第一个6+3硬件
  173. }
  174. else if (BluetoothAim.devicePlan == 2)
  175. {
  176. Acc = new Vector3(-az, ax, -ay) / 32768 * 16;
  177. Gyr = new Vector3(-yaw, roll, -pitch) / 32768 * 2;
  178. Mag = new Vector3(mzr, mxr, -myr) / 32768 * 256;//第二个6+3硬件
  179. }
  180. Gyr = GyrCalibrater.Update(Gyr);
  181. if (GyrCalibrater.Calibration)
  182. {
  183. if (gyrCalibrateCompleteCount < gyrCalibrateTotalCount) {
  184. gyrCalibrateCompleteCount++;
  185. }
  186. }
  187. mag0o = UnityVectorTo0o(Mag);
  188. try {
  189. if (!MagCalibrater.Update(mag0o)) return;
  190. } catch(System.Exception) {
  191. ResetMag();
  192. PopupTip.Show("磁场干扰请远离电子设备");
  193. return;
  194. }
  195. mag0o = MagCalibrater.EllipsoidFitting.Map(mag0o);
  196. Mag = o0VectorToUnity(mag0o);
  197. var ms = (((long)bytes[1]) *60 + bytes[2])*1000 + (long)TwoByteToFloat(bytes[3], bytes[4]);
  198. if(msOld == default)
  199. {
  200. msOld = ms;
  201. return;
  202. }
  203. TimeGap = ms - msOld;
  204. msOld = ms;
  205. GapMs = TimeGap;
  206. gyr0o = UnityVectorTo0o(Gyr);
  207. acc0o = UnityVectorTo0o(Acc);
  208. distanceToAxis.Update(gyr0o, acc0o, mag0o, GapMs);
  209. acc0o = distanceToAxis.AccCorrection(gyr0o, acc0o, GapMs);/**///轴心偏离矫正
  210. Acc = o0VectorToUnity(acc0o);
  211. newRotation = _9Axis.update(Acc, Gyr, Mag, TimeGap);
  212. //if (SB_EventSystem.ins && SB_EventSystem.ins.simulateMouseIsAwaked) {
  213. // SB_EventSystem.ins.MoveSimulateMouse(newRotation);
  214. //} #undetermined
  215. }
  216. o0.Bow.DistanceToAxis distanceToAxis = new o0.Bow.DistanceToAxis();
  217. double GapMs;
  218. o0.Geometry.Vector<double> gyr0o;
  219. o0.Geometry.Vector<double> acc0o;
  220. o0.Geometry.Vector<double> mag0o;
  221. o0.Geometry.Vector<double> UnityVectorTo0o(Vector3 src) {
  222. return new o0.Geometry.Vector<double>(double.Parse(src.x.ToString()), double.Parse(src.y.ToString()), double.Parse(src.z.ToString()));
  223. }
  224. Vector3 o0VectorToUnity(o0.Geometry.Vector<double> src) {
  225. return new Vector3(float.Parse(src.x.ToString()), float.Parse(src.y.ToString()), float.Parse(src.z.ToString()));
  226. }
  227. public void Update()
  228. {
  229. gameRotation = Quaternion.Lerp(gameRotation, newRotation, Time.deltaTime * 7);
  230. _magCompleteTemp = IsMagCompleted();
  231. if (!magComplete && _magCompleteTemp) {
  232. StartCoroutine(SaveMag());
  233. PopupTip.Show("地磁计校准完成");
  234. }
  235. magComplete = _magCompleteTemp;
  236. }
  237. bool _magCompleteTemp;
  238. bool magComplete;
  239. Quaternion newRotation = Quaternion.identity;
  240. public void DoIdentity()
  241. {
  242. _9Axis.SetIdentityAndSave();
  243. Quaternion qua = _9Axis.getLastState().Qua;
  244. newRotation = qua;
  245. gameRotation = qua;
  246. }
  247. }