WorldTracker_3DOF_Orbit.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.Events;
  5. using System.Runtime.InteropServices;
  6. using System.Globalization;
  7. #if ENABLE_INPUT_SYSTEM
  8. using UnityEngine.InputSystem;
  9. #endif
  10. namespace Imagine.WebAR
  11. {
  12. public partial class WorldTracker
  13. {
  14. [System.Serializable]
  15. public class Settings3DOFOrbit
  16. {
  17. public float orbitDistance = 0.4f;
  18. //public bool useExtraSmoothing = false; //extra smoothing by default
  19. [Range(1,50)] public float smoothenFactor = 10;
  20. [Space][Range(.0001f, 0.01f)] public float angleSmoothFactor = 0.001f;
  21. [Range(0f, 0.05f)] public float angleDriftThreshold = 0.025f;
  22. public Transform centerTransform;
  23. public bool swipeToRotate = true;
  24. public float swipeSensitivity = 0.25f;
  25. public bool pinchToScale = true;
  26. public float minDist = 0.25f;
  27. public float maxDist = 2.5f;
  28. }
  29. private Quaternion orbitModeOffset;
  30. private bool isDragging = false;
  31. private Vector3 startDragPos;
  32. private Vector3 startRot;
  33. private Quaternion lastRotOffset = Quaternion.identity;
  34. private bool isPinching = false;
  35. private Vector2 touch0StartPos, touch1StartPos;
  36. private float origDist, startDist;
  37. void Awake_3DOF_Orbit()
  38. {
  39. }
  40. void Start_3DOF_Orbit()
  41. {
  42. #if ENABLE_LEGACY_INPUT_MANAGER
  43. Input.multiTouchEnabled = true;
  44. #endif
  45. var json = "{";
  46. json += "\"MODE\":\"3DOF_ORBIT\",";
  47. json += "\"ANGLE_SMOOTH_FACTOR\":" + s3dof_orbit.angleSmoothFactor.ToStringInvariantCulture() + ",";
  48. json += "\"ANGLE_DRIFT_THRESHOLD\":" + s3dof_orbit.angleDriftThreshold.ToStringInvariantCulture() + ",";
  49. json += "\"USE_COMPASS\":" + (useCompass?"true":"false");
  50. json += "}";
  51. #if !UNITY_EDITOR && UNITY_WEBGL
  52. SetWebGLwTrackerSettings(json);
  53. #endif
  54. orbitModeOffset = Quaternion.identity;
  55. }
  56. void Update_3DOF_Orbit()
  57. {
  58. //update pos
  59. trackerCamera.transform.position = Vector3.Lerp(trackerCamera.transform.position, targetPos3DOF, Time.deltaTime * s3dof_orbit.smoothenFactor);
  60. trackerCamera.transform.rotation = Quaternion.Slerp(trackerCamera.transform.rotation, targetRot3DOF, Time.deltaTime * s3dof_orbit.smoothenFactor);
  61. //Debug.Log("Update Orbit Mode: " + targetPos3DOF + " " + targetRot3DOF);
  62. //swipe to rotate
  63. Update_3DOF_Orbit_SwipeToRotate();
  64. //pinch
  65. Update_3DOF_Orbit_PinchToScale();
  66. }
  67. #if ENABLE_INPUT_SYSTEM
  68. void Update_3DOF_Orbit_SwipeToRotate()
  69. {
  70. var activeTouchCount = 0;
  71. if (Touchscreen.current != null)
  72. {
  73. for (int i = 0; i < Touchscreen.current.touches.Count; i++)
  74. {
  75. var touchPhase = Touchscreen.current.touches[i].phase.ReadValue();
  76. if (touchPhase == UnityEngine.InputSystem.TouchPhase.Began ||
  77. touchPhase == UnityEngine.InputSystem.TouchPhase.Moved ||
  78. touchPhase == UnityEngine.InputSystem.TouchPhase.Stationary)
  79. {
  80. activeTouchCount++;
  81. }
  82. }
  83. }
  84. if (activeTouchCount > 1)
  85. {
  86. isDragging = false;
  87. //return;
  88. }
  89. else
  90. {
  91. if ((Mouse.current != null && Mouse.current.leftButton.wasPressedThisFrame) ||
  92. (Touchscreen.current != null && Touchscreen.current.primaryTouch.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Began))
  93. {
  94. if (Application.isMobilePlatform && Touchscreen.current != null){
  95. startDragPos = Touchscreen.current.primaryTouch.position.ReadValue();
  96. Debug.Log("click touch");
  97. }
  98. else if(Mouse.current != null)
  99. {
  100. startDragPos = Mouse.current.position.ReadValue();
  101. Debug.Log("click mouse");
  102. }
  103. isDragging = true;
  104. }
  105. else if ((Mouse.current != null && Mouse.current.leftButton.wasReleasedThisFrame) ||
  106. (Touchscreen.current != null && Touchscreen.current.primaryTouch.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Ended))
  107. {
  108. isDragging = false;
  109. lastRotOffset = orbitModeOffset;
  110. }
  111. else if (isDragging)
  112. {
  113. Vector2 curDragPos = new Vector2();
  114. if (Application.isMobilePlatform && Touchscreen.current != null){
  115. curDragPos = Touchscreen.current.primaryTouch.position.ReadValue();
  116. }
  117. else if(Mouse.current != null)
  118. {
  119. curDragPos = Mouse.current.position.ReadValue();
  120. }
  121. var x = curDragPos.x - startDragPos.x;
  122. var rotY = x * s3dof_orbit.swipeSensitivity * 1;
  123. orbitModeOffset = lastRotOffset * Quaternion.Euler(0, rotY, 0);
  124. }
  125. }
  126. }
  127. void Update_3DOF_Orbit_PinchToScale()
  128. {
  129. if (Touchscreen.current != null)
  130. {
  131. var activeTouchCount = 0;
  132. for (int i = 0; i < Touchscreen.current.touches.Count; i++)
  133. {
  134. var touchPhase = Touchscreen.current.touches[i].phase.ReadValue();
  135. if (touchPhase == UnityEngine.InputSystem.TouchPhase.Began ||
  136. touchPhase == UnityEngine.InputSystem.TouchPhase.Moved ||
  137. touchPhase == UnityEngine.InputSystem.TouchPhase.Stationary)
  138. {
  139. activeTouchCount++;
  140. }
  141. }
  142. if(activeTouchCount < 2){
  143. return;
  144. }
  145. }
  146. if (Touchscreen.current != null)
  147. {
  148. // Debug.Log("Double touch");
  149. var touch0 = Touchscreen.current.touches[0];
  150. var touch1 = Touchscreen.current.touches[1];
  151. if (touch0.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Began ||
  152. touch1.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Began)
  153. {
  154. touch0StartPos = touch0.position.ReadValue();
  155. touch1StartPos = touch1.position.ReadValue();
  156. isPinching = true;
  157. startDist = s3dof_orbit.orbitDistance;
  158. Debug.Log("Start Pinch");
  159. }
  160. else if (touch0.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Ended ||
  161. touch1.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Ended ||
  162. touch0.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Canceled ||
  163. touch1.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Canceled)
  164. {
  165. isPinching = false;
  166. Debug.Log("End Pinch");
  167. }
  168. if (isPinching)
  169. {
  170. var dStart = (touch1StartPos - touch0StartPos).magnitude;
  171. var pos0 = touch0.position.ReadValue();
  172. var pos1 = touch1.position.ReadValue();
  173. var d = (pos1 - pos0).magnitude;
  174. var dist = d / dStart;
  175. s3dof_orbit.orbitDistance = Mathf.Clamp(startDist / dist, s3dof_orbit.minDist, s3dof_orbit.maxDist);
  176. //Debug.Log("Pinch " + scale.ToString("0.00") + "x");
  177. }
  178. }
  179. else
  180. {
  181. isPinching = false;
  182. }
  183. }
  184. #else
  185. void Update_3DOF_Orbit_SwipeToRotate()
  186. {
  187. if (Input.touchCount > 1)
  188. {
  189. isDragging = false;
  190. //return;
  191. }
  192. else
  193. {
  194. if (Input.GetMouseButtonDown(0))
  195. {
  196. startDragPos = Input.mousePosition;
  197. isDragging = true;
  198. }
  199. else if (Input.GetMouseButtonUp(0))
  200. {
  201. isDragging = false;
  202. lastRotOffset = orbitModeOffset;
  203. }
  204. else if (isDragging)
  205. {
  206. var curDragPos = Input.mousePosition;
  207. var x = curDragPos.x - startDragPos.x;
  208. var rotY = x * s3dof_orbit.swipeSensitivity * 1;
  209. orbitModeOffset = lastRotOffset * Quaternion.Euler(0, rotY, 0);
  210. }
  211. }
  212. }
  213. void Update_3DOF_Orbit_PinchToScale()
  214. {
  215. if (Input.touchCount == 2)
  216. {
  217. Debug.Log("Double touch");
  218. var touch0 = Input.GetTouch(0);
  219. var touch1 = Input.GetTouch(1);
  220. if (touch0.phase == TouchPhase.Began ||
  221. touch1.phase == TouchPhase.Began)
  222. {
  223. touch0StartPos = touch0.position;
  224. touch1StartPos = touch1.position;
  225. isPinching = true;
  226. startDist = s3dof_orbit.orbitDistance;
  227. Debug.Log("Start Pinch");
  228. }
  229. else if (touch0.phase == TouchPhase.Ended ||
  230. touch1.phase == TouchPhase.Ended ||
  231. touch0.phase == TouchPhase.Canceled ||
  232. touch1.phase == TouchPhase.Canceled)
  233. {
  234. isPinching = false;
  235. Debug.Log("End Pinch");
  236. }
  237. if (isPinching)
  238. {
  239. var dStart = (touch1StartPos - touch0StartPos).magnitude;
  240. var pos0 = touch0.position;
  241. var pos1 = touch1.position;
  242. var d = (pos1 - pos0).magnitude;
  243. var dist = d / dStart;
  244. s3dof_orbit.orbitDistance = Mathf.Clamp(startDist / dist, s3dof_orbit.minDist, s3dof_orbit.maxDist);
  245. //Debug.Log("Pinch " + scale.ToString("0.00") + "x");
  246. }
  247. }
  248. else
  249. {
  250. isPinching = false;
  251. }
  252. }
  253. #endif
  254. void UpdateCameraTransform_3DOF_Orbit(string data)
  255. {
  256. var vals = data.Split(new string[] { "," }, System.StringSplitOptions.RemoveEmptyEntries);
  257. trackerCamRot.w = float.Parse(vals[0], CultureInfo.InvariantCulture);
  258. trackerCamRot.x = float.Parse(vals[1], CultureInfo.InvariantCulture);
  259. trackerCamRot.y = float.Parse(vals[2], CultureInfo.InvariantCulture);
  260. trackerCamRot.z = float.Parse(vals[3], CultureInfo.InvariantCulture);
  261. trackerCamRot = orbitModeOffset * trackerCamRot;
  262. trackerCamPos = s3dof_orbit.centerTransform.position - (trackerCamRot * Vector3.forward) * s3dof_orbit.orbitDistance;
  263. targetPos3DOF = trackerCamPos;
  264. targetRot3DOF = trackerCamRot;
  265. // Debug.Log("Orbit Mode: " + targetPos3DOF + " " + targetRot3DOF.eulerAngles);
  266. }
  267. void Reset_3DOF_Orbit()
  268. {
  269. }
  270. }
  271. }