| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 | using System;using UnityEngine;namespace COM3D2.MeidoPhotoStudio.Plugin{    using static CustomGizmo;    public abstract class DragPoint : MonoBehaviour    {        private static readonly int layer = (int) Mathf.Log(LayerMask.GetMask("AbsolutFront"), 2);        public const float defaultAlpha = 0.75f;        private static GameObject dragPointParent;        private const float doubleClickSensitivity = 0.3f;        private Func<Vector3> position;        private Func<Vector3> rotation;        private Collider collider;        private Renderer renderer;        private bool reinitializeDrag;        protected bool Transforming => CurrentDragType >= DragType.MoveXZ;        protected bool Special => CurrentDragType == DragType.Select || CurrentDragType == DragType.Delete;        protected bool Moving => CurrentDragType == DragType.MoveXZ || CurrentDragType == DragType.MoveY;        protected bool Rotating => CurrentDragType >= DragType.RotLocalXZ && CurrentDragType <= DragType.RotLocalY;        protected bool Scaling => CurrentDragType == DragType.Scale;        protected bool Selecting => CurrentDragType == DragType.Select;        protected bool Deleting => CurrentDragType == DragType.Delete;        private Vector3 startMousePosition;        protected static Camera camera = GameMain.Instance.MainCamera.camera;        public enum DragType        {            None, Ignore, Select, Delete,            MoveXZ, MoveY,            RotLocalXZ, RotY, RotLocalY,            Scale        }        public Transform MyObject { get; protected set; }        public GameObject MyGameObject => MyObject.gameObject;        private float startDoubleClick;        private Vector3 screenPoint;        private Vector3 startOffset;        private Vector3 newOffset;        public static Material dragPointMaterial = new Material(Shader.Find("CM3D2/Trans_AbsoluteFront"));        public static readonly Color defaultColour = new Color(0f, 0f, 0f, 0.4f);        public Vector3 OriginalScale { get; private set; }        private Vector3 baseScale;        public Vector3 BaseScale        {            get => baseScale;            protected set            {                baseScale = value;                transform.localScale = BaseScale * DragPointScale;            }        }        private float dragPointScale = 1f;        public float DragPointScale        {            get => dragPointScale;            set            {                dragPointScale = value;                transform.localScale = BaseScale * dragPointScale;            }        }        public GameObject GizmoGo { get; protected set; }        public CustomGizmo Gizmo { get; protected set; }        private DragType oldDragType;        private DragType currentDragType;        protected DragType CurrentDragType        {            get => currentDragType;            set            {                if (value != oldDragType)                {                    currentDragType = value;                    reinitializeDrag = true;                    oldDragType = currentDragType;                    ApplyDragType();                }            }        }        private bool dragPointEnabled = true;        public bool DragPointEnabled        {            get => dragPointEnabled;            set            {                if (dragPointEnabled == value) return;                dragPointEnabled = value;                ApplyDragType();            }        }        private bool gizmoEnabled = true;        public bool GizmoEnabled        {            get => GizmoGo != null && gizmoEnabled;            set            {                if (GizmoGo == null || (gizmoEnabled == value)) return;                gizmoEnabled = value;                ApplyDragType();            }        }        static DragPoint()        {            InputManager.Register(MpsKey.DragSelect, KeyCode.A, "Select handle mode");            InputManager.Register(MpsKey.DragDelete, KeyCode.D, "Delete handle mode");            InputManager.Register(MpsKey.DragMove, KeyCode.Z, "Move handle mode");            InputManager.Register(MpsKey.DragRotate, KeyCode.X, "Rotate handle mode");            InputManager.Register(MpsKey.DragScale, KeyCode.C, "Scale handle mode");            InputManager.Register(MpsKey.DragFinger, KeyCode.Space, "Show finger handles");        }        private void Awake()        {            BaseScale = OriginalScale = transform.localScale;            collider = GetComponent<Collider>();            renderer = GetComponent<Renderer>();            ApplyDragType();        }        private static GameObject DragPointParent()        {            return dragPointParent ? dragPointParent : (dragPointParent = new GameObject("[MPS DragPoint Parent]"));        }        public static T Make<T>(PrimitiveType primitiveType, Vector3 scale) where T : DragPoint        {            GameObject dragPointGo = GameObject.CreatePrimitive(primitiveType);            dragPointGo.transform.SetParent(DragPointParent().transform, false);            dragPointGo.transform.localScale = scale;            dragPointGo.layer = layer;            T dragPoint = dragPointGo.AddComponent<T>();            dragPoint.renderer.material = dragPointMaterial;            dragPoint.renderer.material.color = defaultColour;            return dragPoint;        }        public virtual void Initialize(Func<Vector3> position, Func<Vector3> rotation)        {            this.position = position;            this.rotation = rotation;        }        public virtual void Set(Transform myObject)        {            MyObject = myObject;            gameObject.name = $"[MPS DragPoint: {MyObject.name}]";        }        public virtual void AddGizmo(float scale = 0.25f, GizmoMode mode = GizmoMode.Local)        {            Gizmo = CustomGizmo.Make(MyObject, scale, mode);            GizmoGo = Gizmo.gameObject;            Gizmo.GizmoVisible = false;            ApplyDragType();        }        protected virtual void ApplyDragType() { }        public void ApplyProperties(bool active = false, bool visible = false, bool gizmo = false)        {            collider.enabled = active;            renderer.enabled = visible;            if (Gizmo) Gizmo.GizmoVisible = gizmo;        }        protected void ApplyColour(Color colour) => renderer.material.color = colour;        protected void ApplyColour(float r, float g, float b, float a = defaultAlpha)        {            ApplyColour(new Color(r, g, b, a));        }        protected Vector3 MouseDelta() => Utility.MousePosition - startMousePosition;        protected bool OtherDragType()        {            return InputManager.GetKey(MpsKey.DragSelect) || InputManager.GetKey(MpsKey.DragDelete)                || InputManager.GetKey(MpsKey.DragMove) || InputManager.GetKey(MpsKey.DragRotate)                || InputManager.GetKey(MpsKey.DragScale) || InputManager.GetKey(MpsKey.DragFinger)                || InputManager.Shift;        }        protected Vector3 CursorPosition()        {            Vector3 mousePosition = Utility.MousePosition;            return camera.ScreenToWorldPoint(new Vector3(mousePosition.x, mousePosition.y, screenPoint.z))                + startOffset - newOffset;        }        protected virtual void Update()        {            transform.position = position();            transform.eulerAngles = rotation();            UpdateDragType();        }        protected virtual void OnMouseDown()        {            screenPoint = camera.WorldToScreenPoint(transform.position);            startMousePosition = Utility.MousePosition;            startOffset = transform.position - camera.ScreenToWorldPoint(                new Vector3(startMousePosition.x, startMousePosition.y, screenPoint.z)            );            newOffset = transform.position - MyObject.position;        }        protected virtual void OnMouseDrag()        {            if (reinitializeDrag)            {                reinitializeDrag = false;                OnMouseDown();            }            if (collider.enabled && startMousePosition != Utility.MousePosition) Drag();        }        protected abstract void UpdateDragType();        protected abstract void Drag();        protected virtual void OnMouseUp()        {            if ((Time.time - startDoubleClick) < doubleClickSensitivity)            {                startDoubleClick = -1f;                OnDoubleClick();            }            else            {                startDoubleClick = Time.time;            }        }        protected virtual void OnDoubleClick() { }        private void OnEnable()        {            if (position != null)            {                transform.position = position();                transform.eulerAngles = rotation();            }            if (GizmoGo) GizmoGo.SetActive(true);            ApplyDragType();        }        private void OnDisable()        {            if (GizmoGo) GizmoGo.SetActive(false);        }        protected virtual void OnDestroy() => Destroy(GizmoGo);    }}
 |