ManipulationHandler.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. using SC.XR.Unity.Module_InputSystem.InputDeviceGC;
  2. using SC.XR.Unity.Module_InputSystem.InputDeviceGC.BT3Dof;
  3. using SC.XR.Unity.Module_InputSystem.InputDeviceHand;
  4. using SC.XR.Unity.Module_InputSystem.InputDeviceHead;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using UnityEngine;
  9. using UnityEngine.EventSystems;
  10. namespace SC.XR.Unity.Module_InputSystem
  11. {
  12. public struct SCPose
  13. {
  14. public Vector3 position;
  15. public Quaternion rotation;
  16. public SCPose(Vector3 position, Quaternion rotation)
  17. {
  18. this.position = position;
  19. this.rotation = rotation;
  20. }
  21. }
  22. [RequireComponent(typeof(NearInterationGrabbable))]
  23. [RequireComponent(typeof(BoxCollider))]
  24. public class ManipulationHandler : PointerHandler
  25. {
  26. public Transform Target;
  27. [SerializeField]
  28. protected SCAudiosConfig.AudioType StartAudio = SCAudiosConfig.AudioType.Move_Start;
  29. [SerializeField]
  30. protected SCAudiosConfig.AudioType EndAudio = SCAudiosConfig.AudioType.Move_End;
  31. protected Vector3 TargetRelativeTo;
  32. protected SCPointEventData sCPointEventData;
  33. protected Matrix4x4 matrix;
  34. private Rigidbody rigidBody;
  35. private bool wasKinematic = false;
  36. private IDevicePartManipulation devicePartManipulation;
  37. private IDevicePartCountManipulation devicePartCountManipulation;
  38. private Dictionary<InputDevicePartType, SCPointEventData> eventDataDic;
  39. private ScaleLogic scaleLogic;
  40. private RotateLogic rotateLogic;
  41. private MoveLogic moveLogic;
  42. private Vector3 targetStartScale;
  43. public bool headRotate = false;
  44. public bool oneGameControllerRotate = false;
  45. public bool canOneHandRotate = false;
  46. public bool canTwoHandRotate = false;
  47. public bool canTwoHandScale = false;
  48. public float minScaleRatio = 0.8f;
  49. public float maxScaleRatio = 3f;
  50. public virtual void Start()
  51. {
  52. targetStartScale = Target == null ? transform.localScale : Target.localScale;
  53. }
  54. public override void OnPointerDown(PointerEventData eventData)
  55. {
  56. base.OnPointerDown(eventData);
  57. if (eventDataDic == null)
  58. {
  59. eventDataDic = new Dictionary<InputDevicePartType, SCPointEventData>();
  60. }
  61. if (scaleLogic == null)
  62. {
  63. scaleLogic = new ScaleLogic();
  64. }
  65. if (rotateLogic == null)
  66. {
  67. rotateLogic = new RotateLogic();
  68. }
  69. if (moveLogic == null)
  70. {
  71. moveLogic = new MoveLogic();
  72. }
  73. if (eventData is SCPointEventData)
  74. {
  75. SCPointEventData scPointEventData = eventData as SCPointEventData;
  76. eventDataDic[scPointEventData.inputDevicePartBase.PartType] = scPointEventData;
  77. if (scPointEventData.inputDevicePartBase is InputDeviceHandPart)
  78. {
  79. devicePartManipulation = new HandDevicePartManipulation();
  80. }
  81. else if (scPointEventData.inputDevicePartBase is InputDeviceGCPart)
  82. {
  83. devicePartManipulation = new GameControllerDevicePartManipulation();
  84. }
  85. else if (scPointEventData.inputDevicePartBase is InputDeviceHeadPart)
  86. {
  87. devicePartManipulation = new HeadDevicePartManipulation();
  88. }
  89. }
  90. //Two DevicePart
  91. if (eventDataDic.Count > 1)
  92. {
  93. devicePartCountManipulation = new TwoDevicePartCountManipulation();
  94. devicePartCountManipulation.Init(this, devicePartManipulation, eventDataDic, Target == null ? this.transform : Target.transform, moveLogic, rotateLogic, scaleLogic);
  95. }
  96. //One DevicePart
  97. else if (eventDataDic.Count == 1)
  98. {
  99. devicePartCountManipulation = new OneDevicePartCountManipulation();
  100. devicePartCountManipulation.Init(this, devicePartManipulation, eventDataDic, Target == null ? this.transform : Target.transform, moveLogic, rotateLogic, scaleLogic);
  101. }
  102. rigidBody = Target == null ? this.GetComponent<Rigidbody>() : Target.GetComponent<Rigidbody>();
  103. if (rigidBody != null)
  104. {
  105. wasKinematic = rigidBody.isKinematic;
  106. rigidBody.isKinematic = true;
  107. }
  108. AudioSystem.getInstance.PlayAudioOneShot(gameObject, StartAudio);
  109. }
  110. public override void OnPointerUp(PointerEventData eventData)
  111. {
  112. base.OnPointerUp(eventData);
  113. if (eventData is SCPointEventData)
  114. {
  115. SCPointEventData scPointEventData = eventData as SCPointEventData;
  116. if (eventDataDic.ContainsKey(scPointEventData.inputDevicePartBase.PartType))
  117. {
  118. eventDataDic.Remove(scPointEventData.inputDevicePartBase.PartType);
  119. }
  120. //from two hand to one hand
  121. if (eventDataDic.Count == 1)
  122. {
  123. devicePartCountManipulation = new OneDevicePartCountManipulation();
  124. devicePartCountManipulation.Init(this, devicePartManipulation, eventDataDic, Target == null ? this.transform : Target.transform, moveLogic, rotateLogic, scaleLogic);
  125. }
  126. }
  127. if (rigidBody != null)
  128. {
  129. rigidBody.isKinematic = wasKinematic;
  130. rigidBody = null;
  131. }
  132. AudioSystem.getInstance.PlayAudioOneShot(gameObject, EndAudio);
  133. }
  134. public override void OnDrag(PointerEventData eventData)
  135. {
  136. base.OnDrag(eventData);
  137. sCPointEventData = eventData as SCPointEventData;
  138. if (sCPointEventData == null)
  139. {
  140. return;
  141. }
  142. Tuple<Vector3, Quaternion, Vector3> result = devicePartCountManipulation.Update(CaculateScaleConstraint);
  143. Vector3 position = result.Item1;
  144. Quaternion rotation = result.Item2;
  145. Vector3 scale = result.Item3;
  146. if (Target)
  147. {
  148. Target.position = position;
  149. Target.rotation = rotation;
  150. Target.localScale = scale;
  151. }
  152. else
  153. {
  154. transform.position = position;
  155. transform.rotation = rotation;
  156. transform.localScale = scale;
  157. }
  158. }
  159. public override void OnPointerExit(PointerEventData eventData)
  160. {
  161. base.OnPointerExit(eventData);
  162. }
  163. public override void OnPointerEnter(PointerEventData eventData)
  164. {
  165. base.OnPointerEnter(eventData);
  166. }
  167. public override void OnPointerClick(PointerEventData eventData)
  168. {
  169. base.OnPointerClick(eventData);
  170. }
  171. private Vector3 CaculateScaleConstraint(Vector3 toScale)
  172. {
  173. Vector3 minimumScale = targetStartScale * minScaleRatio;
  174. Vector3 maximumScale = targetStartScale * maxScaleRatio;
  175. if (Vector3.Min(maximumScale, toScale) != toScale)
  176. {
  177. float maxRatio = 0.0f;
  178. int maxIdx = -1;
  179. for (int i = 0; i < 3; i++)
  180. {
  181. if (maximumScale[i] > 0)
  182. {
  183. float ratio = toScale[i] / maximumScale[i];
  184. if (ratio > maxRatio)
  185. {
  186. maxRatio = ratio;
  187. maxIdx = i;
  188. }
  189. }
  190. }
  191. if (maxIdx != -1)
  192. {
  193. toScale /= maxRatio;
  194. }
  195. }
  196. if (Vector3.Max(minimumScale, toScale) != toScale)
  197. {
  198. float minRatio = 1.0f;
  199. int minIdx = -1;
  200. // Find out the component with the minimum ratio to its minimum allowed value
  201. for (int i = 0; i < 3; ++i)
  202. {
  203. if (minimumScale[i] > 0)
  204. {
  205. float ratio = toScale[i] / minimumScale[i];
  206. if (ratio < minRatio)
  207. {
  208. minRatio = ratio;
  209. minIdx = i;
  210. }
  211. }
  212. }
  213. if (minIdx != -1)
  214. {
  215. toScale /= minRatio;
  216. }
  217. }
  218. return toScale;
  219. }
  220. }
  221. }