DragPoint.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. using System;
  2. using UnityEngine;
  3. namespace COM3D2.MeidoPhotoStudio.Plugin
  4. {
  5. using static CustomGizmo;
  6. public abstract class DragPoint : MonoBehaviour
  7. {
  8. private static readonly int layer = (int) Mathf.Log(LayerMask.GetMask("AbsolutFront"), 2);
  9. public const float defaultAlpha = 0.75f;
  10. private static GameObject dragPointParent;
  11. private const float doubleClickSensitivity = 0.3f;
  12. private Func<Vector3> position;
  13. private Func<Vector3> rotation;
  14. private Collider collider;
  15. private Renderer renderer;
  16. private bool reinitializeDrag;
  17. protected bool Transforming => CurrentDragType >= DragType.MoveXZ;
  18. protected bool Special => CurrentDragType == DragType.Select || CurrentDragType == DragType.Delete;
  19. protected bool Moving => CurrentDragType == DragType.MoveXZ || CurrentDragType == DragType.MoveY;
  20. protected bool Rotating => CurrentDragType >= DragType.RotLocalXZ && CurrentDragType <= DragType.RotLocalY;
  21. protected bool Scaling => CurrentDragType == DragType.Scale;
  22. protected bool Selecting => CurrentDragType == DragType.Select;
  23. protected bool Deleting => CurrentDragType == DragType.Delete;
  24. private Vector3 startMousePosition;
  25. protected static Camera camera = GameMain.Instance.MainCamera.camera;
  26. public enum DragType
  27. {
  28. None, Ignore, Select, Delete,
  29. MoveXZ, MoveY,
  30. RotLocalXZ, RotY, RotLocalY,
  31. Scale
  32. }
  33. public Transform MyObject { get; protected set; }
  34. public GameObject MyGameObject => MyObject.gameObject;
  35. private float startDoubleClick;
  36. private Vector3 screenPoint;
  37. private Vector3 startOffset;
  38. private Vector3 newOffset;
  39. public static Material dragPointMaterial = new Material(Shader.Find("CM3D2/Trans_AbsoluteFront"));
  40. public static readonly Color defaultColour = new Color(0f, 0f, 0f, 0.4f);
  41. public Vector3 OriginalScale { get; private set; }
  42. private Vector3 baseScale;
  43. public Vector3 BaseScale
  44. {
  45. get => baseScale;
  46. protected set
  47. {
  48. baseScale = value;
  49. transform.localScale = BaseScale * DragPointScale;
  50. }
  51. }
  52. private float dragPointScale = 1f;
  53. public float DragPointScale
  54. {
  55. get => dragPointScale;
  56. set
  57. {
  58. dragPointScale = value;
  59. transform.localScale = BaseScale * dragPointScale;
  60. }
  61. }
  62. public GameObject GizmoGo { get; protected set; }
  63. public CustomGizmo Gizmo { get; protected set; }
  64. private DragType oldDragType;
  65. private DragType currentDragType;
  66. protected DragType CurrentDragType
  67. {
  68. get => currentDragType;
  69. set
  70. {
  71. if (value != oldDragType)
  72. {
  73. currentDragType = value;
  74. reinitializeDrag = true;
  75. oldDragType = currentDragType;
  76. ApplyDragType();
  77. }
  78. }
  79. }
  80. private bool dragPointEnabled = true;
  81. public bool DragPointEnabled
  82. {
  83. get => dragPointEnabled;
  84. set
  85. {
  86. if (dragPointEnabled == value) return;
  87. dragPointEnabled = value;
  88. ApplyDragType();
  89. }
  90. }
  91. private bool gizmoEnabled = true;
  92. public bool GizmoEnabled
  93. {
  94. get => GizmoGo != null && gizmoEnabled;
  95. set
  96. {
  97. if (GizmoGo == null || (gizmoEnabled == value)) return;
  98. gizmoEnabled = value;
  99. ApplyDragType();
  100. }
  101. }
  102. static DragPoint()
  103. {
  104. InputManager.Register(MpsKey.DragSelect, KeyCode.A, "Select handle mode");
  105. InputManager.Register(MpsKey.DragDelete, KeyCode.D, "Delete handle mode");
  106. InputManager.Register(MpsKey.DragMove, KeyCode.Z, "Move handle mode");
  107. InputManager.Register(MpsKey.DragRotate, KeyCode.X, "Rotate handle mode");
  108. InputManager.Register(MpsKey.DragScale, KeyCode.C, "Scale handle mode");
  109. InputManager.Register(MpsKey.DragFinger, KeyCode.Space, "Show finger handles");
  110. }
  111. private void Awake()
  112. {
  113. BaseScale = OriginalScale = transform.localScale;
  114. collider = GetComponent<Collider>();
  115. renderer = GetComponent<Renderer>();
  116. ApplyDragType();
  117. }
  118. private static GameObject DragPointParent()
  119. {
  120. return dragPointParent ? dragPointParent : (dragPointParent = new GameObject("[MPS DragPoint Parent]"));
  121. }
  122. public static T Make<T>(PrimitiveType primitiveType, Vector3 scale) where T : DragPoint
  123. {
  124. GameObject dragPointGo = GameObject.CreatePrimitive(primitiveType);
  125. dragPointGo.transform.SetParent(DragPointParent().transform, false);
  126. dragPointGo.transform.localScale = scale;
  127. dragPointGo.layer = 8;
  128. T dragPoint = dragPointGo.AddComponent<T>();
  129. dragPoint.renderer.material = dragPointMaterial;
  130. dragPoint.renderer.material.color = defaultColour;
  131. return dragPoint;
  132. }
  133. public virtual void Initialize(Func<Vector3> position, Func<Vector3> rotation)
  134. {
  135. this.position = position;
  136. this.rotation = rotation;
  137. }
  138. public virtual void Set(Transform myObject)
  139. {
  140. MyObject = myObject;
  141. gameObject.name = $"[MPS DragPoint: {MyObject.name}]";
  142. }
  143. public virtual void AddGizmo(float scale = 0.25f, GizmoMode mode = GizmoMode.Local)
  144. {
  145. Gizmo = CustomGizmo.Make(MyObject, scale, mode);
  146. GizmoGo = Gizmo.gameObject;
  147. Gizmo.GizmoVisible = false;
  148. ApplyDragType();
  149. }
  150. protected virtual void ApplyDragType() { }
  151. public void ApplyProperties(bool active = false, bool visible = false, bool gizmo = false)
  152. {
  153. collider.enabled = active;
  154. renderer.enabled = visible;
  155. if (Gizmo) Gizmo.GizmoVisible = gizmo;
  156. }
  157. protected void ApplyColour(Color colour) => renderer.material.color = colour;
  158. protected void ApplyColour(float r, float g, float b, float a = defaultAlpha)
  159. {
  160. ApplyColour(new Color(r, g, b, a));
  161. }
  162. protected Vector3 MouseDelta() => Utility.MousePosition - startMousePosition;
  163. protected bool OtherDragType()
  164. {
  165. return InputManager.GetKey(MpsKey.DragSelect) || InputManager.GetKey(MpsKey.DragDelete)
  166. || InputManager.GetKey(MpsKey.DragMove) || InputManager.GetKey(MpsKey.DragRotate)
  167. || InputManager.GetKey(MpsKey.DragScale) || InputManager.GetKey(MpsKey.DragFinger)
  168. || InputManager.Shift;
  169. }
  170. protected Vector3 CursorPosition()
  171. {
  172. Vector3 mousePosition = Utility.MousePosition;
  173. return camera.ScreenToWorldPoint(new Vector3(mousePosition.x, mousePosition.y, screenPoint.z))
  174. + startOffset - newOffset;
  175. }
  176. protected virtual void Update()
  177. {
  178. transform.position = position();
  179. transform.eulerAngles = rotation();
  180. UpdateDragType();
  181. }
  182. protected virtual void OnMouseDown()
  183. {
  184. screenPoint = camera.WorldToScreenPoint(transform.position);
  185. startMousePosition = Utility.MousePosition;
  186. startOffset = transform.position - camera.ScreenToWorldPoint(
  187. new Vector3(startMousePosition.x, startMousePosition.y, screenPoint.z)
  188. );
  189. newOffset = transform.position - MyObject.position;
  190. }
  191. protected virtual void OnMouseDrag()
  192. {
  193. if (reinitializeDrag)
  194. {
  195. reinitializeDrag = false;
  196. OnMouseDown();
  197. }
  198. if (collider.enabled && startMousePosition != Utility.MousePosition) Drag();
  199. }
  200. protected abstract void UpdateDragType();
  201. protected abstract void Drag();
  202. protected virtual void OnMouseUp()
  203. {
  204. if ((Time.time - startDoubleClick) < doubleClickSensitivity)
  205. {
  206. startDoubleClick = -1f;
  207. OnDoubleClick();
  208. }
  209. else
  210. {
  211. startDoubleClick = Time.time;
  212. }
  213. }
  214. protected virtual void OnDoubleClick() { }
  215. private void OnEnable()
  216. {
  217. if (position != null)
  218. {
  219. transform.position = position();
  220. transform.eulerAngles = rotation();
  221. }
  222. if (GizmoGo) GizmoGo.SetActive(true);
  223. ApplyDragType();
  224. }
  225. private void OnDisable()
  226. {
  227. if (GizmoGo) GizmoGo.SetActive(false);
  228. }
  229. protected virtual void OnDestroy() => Destroy(GizmoGo);
  230. }
  231. }