Browse Source

Revamp Dragpoints

Rewrite maid IK Dragpoints and manager
Make general dragpoint that props, lights, etc derive from
Make MPSLight a DragPointGeneral derived component
Prop dragpoints now have a gizmo when rotating

Some polishing and testing required
habeebweeb 4 years ago
parent
commit
9cb7e8540a
33 changed files with 1820 additions and 2687 deletions
  1. 0 207
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/DragDogu.cs
  2. 8 9
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/CustomGizmo.cs
  3. 199 0
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/DragPoint/DragPoint.cs
  4. 177 0
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/DragPoint/DragPointGeneral.cs
  5. 79 90
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/MPSLight.cs
  6. 66 0
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/DragPoint/DragPointMeido.cs
  7. 42 0
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/DragPoint/DragPointOther.cs
  8. 2 3
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/BackgroundWindow2Panes/AttachPropPane.cs
  9. 3 3
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/BackgroundWindowPanes/DragPointPane.cs
  10. 4 4
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/BackgroundWindowPanes/LightsPane.cs
  11. 0 868
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/DragPointManager.cs
  12. 17 28
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/EnvironmentManager.cs
  13. 39 106
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/LightManager.cs
  14. 1 1
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/MeidoManager.cs
  15. 25 61
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/PropManager.cs
  16. 0 270
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/BaseDrag.cs
  17. 0 162
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragBody.cs
  18. 0 132
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragHead.cs
  19. 0 116
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragJointFinger.cs
  20. 0 102
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragJointForearm.cs
  21. 0 133
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragJointHand.cs
  22. 0 91
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragMune.cs
  23. 0 64
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragPelvis.cs
  24. 148 0
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragPointChain.cs
  25. 94 0
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragPointFinger.cs
  26. 121 0
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragPointHead.cs
  27. 62 0
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragPointPelvis.cs
  28. 91 0
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragPointSpine.cs
  29. 87 0
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragPointTorso.cs
  30. 0 82
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragSpine.cs
  31. 0 91
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragTorso.cs
  32. 26 64
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/Meido.cs
  33. 529 0
      COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/MeidoDragPointManager.cs

+ 0 - 207
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/DragDogu.cs

@@ -1,207 +0,0 @@
-using System;
-using UnityEngine;
-
-namespace COM3D2.MeidoPhotoStudio.Plugin
-{
-    using static CustomGizmo;
-    internal class DragDogu : BaseDrag
-    {
-        private Vector3 off;
-        private Vector3 off2;
-        private float doguScale;
-        private Quaternion doguRotation;
-        public GameObject Dogu { get; private set; }
-        public event EventHandler Delete;
-        public event EventHandler Rotate;
-        public event EventHandler Scale;
-        public event EventHandler Select;
-        public bool DeleteMe { get; private set; }
-        public string Name => Dogu.name;
-        public DragPointManager.AttachPointInfo attachPointInfo = DragPointManager.AttachPointInfo.Empty;
-        public bool keepDogu = false;
-        public float scaleFactor = 1f;
-
-        public DragDogu Initialize(GameObject dogu, bool keepDogu = false)
-        {
-            return Initialize(dogu, keepDogu, GizmoMode.World,
-                () => this.Dogu.transform.position,
-                () => Vector3.zero
-            );
-        }
-
-        public DragDogu Initialize(GameObject dogu, bool keepDogu, GizmoMode mode,
-            Func<Vector3> position, Func<Vector3> rotation
-        )
-        {
-            this.keepDogu = keepDogu;
-            this.Dogu = dogu;
-            base.InitializeDragPoint(position, rotation);
-            InitializeGizmo(this.Dogu.transform, 1f, mode);
-            gizmo.GizmoDrag += (s, a) =>
-            {
-                if (CurrentDragType == DragType.RotLocalY || CurrentDragType == DragType.RotLocalXZ)
-                {
-                    OnRotate();
-                }
-            };
-            return this;
-        }
-
-        protected override void Update()
-        {
-            float distance = Vector3.Distance(Camera.main.transform.position, transform.position);
-            transform.localScale = Vector3.one * (0.4f * InitialScale.x * DragPointScale * distance);
-            base.Update();
-        }
-
-        protected override void GetDragType()
-        {
-            bool holdShift = Utility.GetModKey(Utility.ModKey.Shift);
-            if (Input.GetKey(KeyCode.A))
-            {
-                CurrentDragType = DragType.Select;
-                CurrentGizmoType = GizmoType.None;
-            }
-            else if (Input.GetKey(KeyCode.D))
-            {
-                CurrentDragType = DragType.Delete;
-                CurrentGizmoType = GizmoType.None;
-            }
-            else if (Input.GetKey(KeyCode.Z))
-            {
-                if (Utility.GetModKey(Utility.ModKey.Control)) CurrentDragType = DragType.MoveY;
-                else CurrentDragType = holdShift ? DragType.RotY : DragType.MoveXZ;
-                CurrentGizmoType = GizmoType.None;
-            }
-            else if (Input.GetKey(KeyCode.X))
-            {
-                CurrentDragType = holdShift ? DragType.RotLocalY : DragType.RotLocalXZ;
-                CurrentGizmoType = GizmoType.Rotate;
-            }
-            else if (Input.GetKey(KeyCode.C))
-            {
-                CurrentDragType = DragType.Scale;
-                CurrentGizmoType = GizmoType.None;
-            }
-            else
-            {
-                CurrentDragType = DragType.None;
-                CurrentGizmoType = GizmoType.None;
-            }
-        }
-
-        protected override void InitializeDrag()
-        {
-            if (CurrentDragType == DragType.Delete)
-            {
-                this.DeleteMe = true;
-                this.Delete?.Invoke(this, EventArgs.Empty);
-                return;
-            }
-
-            if (CurrentDragType == DragType.Select)
-            {
-                this.Select?.Invoke(this, EventArgs.Empty);
-                return;
-            }
-
-            base.InitializeDrag();
-
-            doguScale = Dogu.transform.localScale.x;
-            doguRotation = Dogu.transform.rotation;
-            off = transform.position - Camera.main.ScreenToWorldPoint(
-                new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z)
-            );
-            off2 = new Vector3(
-                transform.position.x - Dogu.transform.position.x,
-                transform.position.y - Dogu.transform.position.y,
-                transform.position.z - Dogu.transform.position.z
-            );
-        }
-
-        protected override void DoubleClick()
-        {
-            if (CurrentDragType == DragType.Scale)
-            {
-                Dogu.transform.localScale = new Vector3(1f, 1f, 1f);
-                OnScale();
-            }
-            if (CurrentDragType == DragType.RotLocalY || CurrentDragType == DragType.RotLocalXZ)
-            {
-                Dogu.transform.rotation = Quaternion.identity;
-                OnRotate();
-            }
-        }
-
-        protected override void Drag()
-        {
-            if (CurrentDragType == DragType.Select || CurrentDragType == DragType.Delete) return;
-
-            Vector3 pos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z)) + off - off2;
-
-            if (CurrentDragType == DragType.MoveXZ)
-            {
-                Dogu.transform.position = new Vector3(pos.x, Dogu.transform.position.y, pos.z);
-            }
-
-            if (CurrentDragType == DragType.MoveY)
-            {
-                Dogu.transform.position = new Vector3(Dogu.transform.position.x, pos.y, Dogu.transform.position.z);
-            }
-
-            if (CurrentDragType == DragType.RotY)
-            {
-                Vector3 mouseDelta = Input.mousePosition - mousePos;
-
-                Dogu.transform.rotation = doguRotation;
-                Dogu.transform.Rotate(Vector3.up, doguRotation.y - mouseDelta.x / 3f, Space.World);
-                OnRotate();
-            }
-
-            if (CurrentDragType == DragType.RotLocalXZ)
-            {
-                Vector3 mouseDelta = Input.mousePosition - mousePos;
-                Vector3 cameraDirectionForward = Camera.main.transform.TransformDirection(Vector3.forward);
-                Vector3 cameraDirectionRight = Camera.main.transform.TransformDirection(Vector3.right);
-
-                Dogu.transform.rotation = doguRotation;
-                Dogu.transform.Rotate(cameraDirectionForward, doguRotation.x - mouseDelta.x / 3f, Space.World);
-                Dogu.transform.Rotate(cameraDirectionRight, doguRotation.y + mouseDelta.y / 3f, Space.World);
-                OnRotate();
-            }
-
-            if (CurrentDragType == DragType.RotLocalY)
-            {
-                Vector3 mouseDelta = Input.mousePosition - mousePos;
-
-                Dogu.transform.rotation = doguRotation;
-                Dogu.transform.Rotate(Vector3.up * (-mouseDelta.x / 2.2f));
-                OnRotate();
-            }
-
-            if (CurrentDragType == DragType.Scale)
-            {
-                Vector3 posOther = Input.mousePosition - mousePos;
-                float scale = doguScale + (posOther.y / 200f) * scaleFactor;
-                if (scale < 0.1f) scale = 0.1f;
-                Dogu.transform.localScale = new Vector3(scale, scale, scale);
-                OnScale();
-            }
-        }
-
-        private void OnRotate()
-        {
-            Rotate?.Invoke(this, EventArgs.Empty);
-        }
-
-        private void OnScale()
-        {
-            Scale?.Invoke(this, EventArgs.Empty);
-        }
-
-        private void OnDestroy()
-        {
-            if (!keepDogu) GameObject.Destroy(this.Dogu);
-        }
-    }
-}

+ 8 - 9
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/CustomGizmo.cs

@@ -6,6 +6,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 {
     internal class CustomGizmo : GizmoRender
     {
+        private static Camera camera = GameMain.Instance.MainCamera.camera;
         private Transform target;
         private FieldInfo beSelectedType = Utility.GetFieldInfo<GizmoRender>("beSelectedType");
         private int SelectedType => (int)beSelectedType.GetValue(this);
@@ -44,7 +45,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             Local, World, Global
         }
 
-        public static GameObject MakeGizmo(Transform target, float scale = 0.25f, GizmoMode mode = GizmoMode.Local)
+        public static CustomGizmo Make(Transform target, float scale = 0.25f, GizmoMode mode = GizmoMode.Local)
         {
             GameObject gizmoGo = new GameObject();
             gizmoGo.transform.SetParent(target);
@@ -56,7 +57,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             gizmo.gizmoMode = mode;
             gizmo.CurrentGizmoType = GizmoType.Rotate;
 
-            return gizmoGo;
+            return gizmo;
         }
 
         public override void Update()
@@ -90,6 +91,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         private void SetTargetTransform()
         {
+            bool dragged = false;
             switch (gizmoMode)
             {
                 case GizmoMode.Local:
@@ -99,19 +101,16 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                     target.transform.localScale += deltaScale;
                     if (deltaLocalRotation != Quaternion.identity || deltaLocalPosition != Vector3.zero
                         || deltaScale != Vector3.zero
-                    )
-                    {
-                        OnGizmoDrag();
-                    }
+                    ) dragged = true;
                     break;
                 case GizmoMode.World:
                 case GizmoMode.Global:
                     target.transform.position += deltaPosition;
                     target.transform.rotation = deltaRotation * target.transform.rotation;
-                    if (deltaRotation != Quaternion.identity || deltaPosition != Vector3.zero) OnGizmoDrag();
+                    if (deltaRotation != Quaternion.identity || deltaPosition != Vector3.zero) dragged = true;
                     break;
-
             }
+            if (dragged) OnGizmoDrag();
         }
 
         private void SetTransform()
@@ -129,7 +128,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 case GizmoMode.Global:
                     transform.position = target.transform.position;
                     transform.rotation = Quaternion.LookRotation(
-                        transform.position - Camera.main.transform.position, transform.up
+                        transform.position - camera.transform.position, transform.up
                     );
                     break;
             }

+ 199 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/DragPoint/DragPoint.cs

@@ -0,0 +1,199 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    using static CustomGizmo;
+    internal abstract class DragPoint : MonoBehaviour
+    {
+        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 && CurrentDragType <= DragType.RotLocalY;
+        protected bool Moving => CurrentDragType == DragType.MoveXZ || CurrentDragType == DragType.MoveY;
+        protected bool Rotating => CurrentDragType >= DragType.RotLocalXZ && CurrentDragType <= DragType.RotLocalY;
+        protected bool Special => CurrentDragType == DragType.Select || 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 LightBlue = new Material(Shader.Find("Transparent/Diffuse"))
+        {
+            color = new Color(0.4f, 0.4f, 1f, 0.3f)
+        };
+        public static Material Blue = new Material(Shader.Find("Transparent/Diffuse"))
+        {
+            color = new Color(0.5f, 0.5f, 1f, 0.8f)
+        };
+        public Vector3 BaseScale { get; private set; }
+        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 void Awake()
+        {
+            this.BaseScale = transform.localScale;
+            this.collider = GetComponent<Collider>();
+            this.renderer = GetComponent<Renderer>();
+            ApplyDragType();
+        }
+
+        public static T Make<T>(PrimitiveType primitiveType, Vector3 scale, Material material) where T : DragPoint
+        {
+            GameObject dragPoint = GameObject.CreatePrimitive(primitiveType);
+            dragPoint.transform.localScale = scale;
+            dragPoint.GetComponent<Renderer>().material = material;
+            dragPoint.layer = 8;
+
+            return dragPoint.AddComponent<T>();
+        }
+
+        public virtual void Initialize(Func<Vector3> position, Func<Vector3> rotation)
+        {
+            this.position = position;
+            this.rotation = rotation;
+        }
+
+        public virtual void Set(Transform myObject)
+        {
+            this.MyObject = myObject;
+        }
+
+        public virtual void AddGizmo(float scale = 0.25f, GizmoMode mode = GizmoMode.Local)
+        {
+            Gizmo = CustomGizmo.Make(this.MyObject, scale, mode);
+            GizmoGo = Gizmo.gameObject;
+            GizmoGo.SetActive(false);
+            ApplyDragType();
+        }
+
+        protected virtual void ApplyDragType() { }
+
+        public void ApplyProperties(bool active = false, bool visible = false, bool gizmo = false)
+        {
+            this.collider.enabled = active;
+            this.renderer.enabled = visible;
+            this.GizmoGo?.SetActive(gizmo);
+        }
+
+        protected Vector3 MouseDelta() => Input.mousePosition - startMousePosition;
+
+        protected bool OtherDragType()
+        {
+            return Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.D)
+                || Input.GetKey(KeyCode.Z) || Input.GetKey(KeyCode.X) || Input.GetKey(KeyCode.C);
+        }
+
+        protected Vector3 CursorPosition()
+        {
+            Vector3 mousePosition = Input.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 = Input.mousePosition;
+            startOffset = transform.position - camera.ScreenToWorldPoint(
+                new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z)
+            );
+            newOffset = transform.position - MyObject.position;
+        }
+
+        protected virtual void OnMouseDrag()
+        {
+            if (reinitializeDrag)
+            {
+                reinitializeDrag = false;
+                OnMouseDown();
+            }
+
+            if (collider.enabled && Input.mousePosition != startMousePosition) 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();
+            }
+            ApplyDragType();
+        }
+
+        private void OnDisable()
+        {
+            if (GizmoGo) GizmoGo.SetActive(false);
+        }
+
+        protected virtual void OnDestroy() => GameObject.Destroy(GizmoGo);
+    }
+}

+ 177 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/DragPoint/DragPointGeneral.cs

@@ -0,0 +1,177 @@
+using System;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    using static CustomGizmo;
+
+    internal abstract class DragPointGeneral : DragPoint
+    {
+        public const float smallCube = 0.5f;
+        private float currentScale;
+        private bool scaling;
+        private Quaternion currentRotation;
+        public float ScaleFactor { get; set; } = 1f;
+        public bool ConstantScale { get; set; }
+        public event EventHandler Rotate;
+        public event EventHandler Scale;
+        public event EventHandler EndScale;
+        public event EventHandler Delete;
+        public event EventHandler Select;
+
+        public override void AddGizmo(float scale = 1f, GizmoMode mode = GizmoMode.Local)
+        {
+            base.AddGizmo(scale, mode);
+            Gizmo.GizmoDrag += (s, a) =>
+            {
+                if (Gizmo.CurrentGizmoType == GizmoType.Rotate) OnRotate();
+            };
+        }
+
+        protected override void Update()
+        {
+            base.Update();
+
+            if (ConstantScale)
+            {
+                float distance = Vector3.Distance(camera.transform.position, transform.position);
+                transform.localScale = Vector3.one * (0.4f * BaseScale.x * DragPointScale * distance);
+            }
+        }
+
+        protected override void UpdateDragType()
+        {
+            bool shift = Utility.GetModKey(Utility.ModKey.Shift);
+            if (Input.GetKey(KeyCode.A))
+            {
+                CurrentDragType = DragType.Select;
+            }
+            else if (Input.GetKey(KeyCode.D))
+            {
+                CurrentDragType = DragType.Delete;
+            }
+            else if (Input.GetKey(KeyCode.Z))
+            {
+                if (Utility.GetModKey(Utility.ModKey.Control)) CurrentDragType = DragType.MoveY;
+                else CurrentDragType = shift ? DragType.RotY : DragType.MoveXZ;
+            }
+            else if (Input.GetKey(KeyCode.X))
+            {
+                CurrentDragType = shift ? DragType.RotLocalY : DragType.RotLocalXZ;
+            }
+            else if (Input.GetKey(KeyCode.C))
+            {
+                CurrentDragType = DragType.Scale;
+            }
+            else
+            {
+                CurrentDragType = DragType.None;
+            }
+        }
+
+        protected override void OnMouseDown()
+        {
+            if (CurrentDragType == DragType.Delete)
+            {
+                OnDelete();
+                return;
+            }
+
+            if (CurrentDragType == DragType.Select)
+            {
+                OnSelect();
+                return;
+            }
+
+            base.OnMouseDown();
+
+            currentScale = this.MyObject.localScale.x;
+            currentRotation = this.MyObject.rotation;
+        }
+
+        protected override void OnDoubleClick()
+        {
+            if (CurrentDragType == DragType.Scale)
+            {
+                this.MyObject.localScale = Vector3.one;
+                OnScale();
+                OnEndScale();
+            }
+
+            if (CurrentDragType == DragType.RotLocalY || CurrentDragType == DragType.RotLocalXZ)
+            {
+                this.MyObject.rotation = Quaternion.identity;
+                OnRotate();
+            }
+        }
+
+        protected override void OnMouseUp()
+        {
+            base.OnMouseUp();
+            if (scaling)
+            {
+                scaling = false;
+                OnScale();
+                OnEndScale();
+            }
+        }
+
+        protected override void Drag()
+        {
+            if (CurrentDragType == DragType.Select || CurrentDragType == DragType.Delete) return;
+
+            Vector3 cursorPosition = CursorPosition();
+            Vector3 mouseDelta = MouseDelta();
+
+            if (CurrentDragType == DragType.MoveXZ)
+            {
+                MyObject.position = new Vector3(cursorPosition.x, MyObject.position.y, cursorPosition.z);
+            }
+
+            if (CurrentDragType == DragType.MoveY)
+            {
+                MyObject.position = new Vector3(
+                    MyObject.position.x, cursorPosition.y, MyObject.position.z
+                );
+            }
+
+            if (CurrentDragType == DragType.RotY)
+            {
+                MyObject.rotation = currentRotation;
+                MyObject.Rotate(Vector3.up, -mouseDelta.x / 3f, Space.World);
+                OnRotate();
+            }
+
+            if (CurrentDragType == DragType.RotLocalXZ)
+            {
+                MyObject.rotation = currentRotation;
+                MyObject.Rotate(Vector3.forward, mouseDelta.x / 3f, Space.World);
+                MyObject.Rotate(Vector3.right, -mouseDelta.y / 3f, Space.World);
+                OnRotate();
+            }
+
+            if (CurrentDragType == DragType.RotLocalY)
+            {
+                MyObject.rotation = currentRotation;
+                MyObject.Rotate(Vector3.up * -mouseDelta.x / 2.2f);
+                OnRotate();
+            }
+
+            if (CurrentDragType == DragType.Scale)
+            {
+                scaling = true;
+                float scale = currentScale + (mouseDelta.y / 200f) * ScaleFactor;
+                if (scale < 0.1f) scale = 0.1f;
+                MyObject.localScale = new Vector3(scale, scale, scale);
+                OnScale();
+            }
+        }
+
+        protected virtual void OnEndScale() => OnEvent(EndScale);
+        protected virtual void OnScale() => OnEvent(Scale);
+        protected virtual void OnRotate() => OnEvent(Rotate);
+        protected virtual void OnSelect() => OnEvent(Select);
+        protected virtual void OnDelete() => OnEvent(Delete);
+        private void OnEvent(EventHandler handler) => handler?.Invoke(this, EventArgs.Empty);
+    }
+}

+ 79 - 90
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/MPSLight.cs

@@ -3,19 +3,30 @@ using UnityEngine;
 
 namespace COM3D2.MeidoPhotoStudio.Plugin
 {
-    internal class MPSLight
+    internal class DragPointLight : DragPointGeneral
     {
-        private static Camera camera = GameMain.Instance.MainCamera.GetComponent<Camera>();
         private Light light;
-        public DragDogu DragLight { get; private set; }
-        public event EventHandler Rotate;
-        public event EventHandler Scale;
-        public event EventHandler Delete;
-        public event EventHandler Select;
-        public bool isActiveLight = false;
-        public bool IsMain { get; private set; } = false;
+        public enum MPSLightType
+        {
+            Normal, Spot, Point, Disabled
+        }
+        public enum LightProp
+        {
+            LightRotX, LightRotY, Intensity, ShadowStrength, SpotAngle, Range, Red, Green, Blue
+        }
+
+        public bool IsActiveLight { get; set; } = false;
+        public string Name { get; private set; } = String.Empty;
+        public bool IsMain { get; set; } = false;
+        public MPSLightType SelectedLightType { get; private set; } = MPSLightType.Normal;
+        public LightProperty CurrentLightProperty => LightProperties[(int)SelectedLightType];
+        private LightProperty[] LightProperties = new LightProperty[]
+        {
+            new LightProperty(),
+            new LightProperty(),
+            new LightProperty()
+        };
         private bool isDisabled = false;
-        public string Name { get; private set; }
         public bool IsDisabled
         {
             get => isDisabled;
@@ -25,12 +36,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 this.light.gameObject.SetActive(!this.isDisabled);
             }
         }
-        public LightProperty[] LightProperties = new LightProperty[]
-        {
-            new LightProperty(),
-            new LightProperty(),
-            new LightProperty()
-        };
         private bool isColourMode = false;
         public bool IsColourMode
         {
@@ -43,8 +48,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 LightColour = this.isColourMode ? camera.backgroundColor : light.color;
             }
         }
-        public MPSLightType SelectedLightType { get; private set; } = MPSLightType.Normal;
-        public LightProperty CurrentLightProperty => LightProperties[(int)SelectedLightType];
         public Quaternion Rotation
         {
             get => CurrentLightProperty.Rotation;
@@ -111,46 +114,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 else this.light.color = colour;
             }
         }
-        public enum LightProp
-        {
-            LightRotX, LightRotY, Intensity, ShadowStrength, SpotAngle, Range, Red, Green, Blue
-        }
-
-        public enum MPSLightType
-        {
-            Normal, Spot, Point, Disabled
-        }
-
-        public MPSLight(GameObject lightGo = null, bool isMain = false)
-        {
-            this.IsMain = isMain;
-
-            GameObject gameobject = lightGo ?? new GameObject();
-            this.light = gameobject.GetOrAddComponent<Light>();
-
-            float spotAngle = CurrentLightProperty.SpotAngle;
-            this.light.transform.position = LightProperty.DefaultPosition;
-            this.light.transform.rotation = LightProperty.DefaultRotation;
-
-            DragLight = BaseDrag.MakeDragPoint<DragDogu>(
-                PrimitiveType.Cube, Vector3.one * 0.12f, BaseDrag.LightBlue
-            ).Initialize(this.light.gameObject, this.IsMain, CustomGizmo.GizmoMode.World,
-                () => this.light.transform.position,
-                () => this.light.transform.eulerAngles
-            );
-
-            DragLight.scaleFactor = 50f;
-            DragLight.Select += (s, a) => this.Select?.Invoke(this, EventArgs.Empty);
-
-            if (!isMain)
-            {
-                DragLight.Delete += (s, a) => Delete?.Invoke(this, EventArgs.Empty);
-            }
-
-            DragLight.SetDragProp(false, false, false);
-
-            SetLightType(LightType.Directional);
-        }
 
         public static void SetLightProperties(Light light, LightProperty prop)
         {
@@ -170,18 +133,67 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
         }
 
-        public void Destroy()
+        public override void Set(Transform myObject)
+        {
+            base.Set(myObject);
+            this.light = myObject.gameObject.GetOrAddComponent<Light>();
+
+            this.light.transform.position = LightProperty.DefaultPosition;
+            this.light.transform.rotation = LightProperty.DefaultRotation;
+
+            SetLightType(LightType.Directional);
+            this.ScaleFactor = 50f;
+        }
+
+        protected override void OnDestroy()
         {
-            DragLight.Rotate -= OnRotate;
-            DragLight.Scale -= OnScale;
-            GameObject.Destroy(DragLight.gameObject);
             if (!IsMain) GameObject.Destroy(this.light.gameObject);
+            base.OnDestroy();
+        }
+
+        protected override void OnRotate()
+        {
+            CurrentLightProperty.Rotation = light.transform.rotation;
+            base.OnRotate();
+        }
+
+        protected override void OnScale()
+        {
+            float value = light.transform.localScale.x;
+            if (SelectedLightType == MPSLightType.Point) Range = value;
+            else if (SelectedLightType == MPSLightType.Spot) SpotAngle = value;
+            base.OnScale();
+        }
+
+        protected override void ApplyDragType()
+        {
+            DragType current = CurrentDragType;
+            if (current == DragType.Select || current == DragType.MoveXZ || current == DragType.MoveY)
+            {
+                ApplyProperties(true, true, false);
+            }
+            else if (current == DragType.RotY || current == DragType.RotLocalXZ || current == DragType.RotLocalY)
+            {
+                bool canRotate = SelectedLightType != MPSLightType.Point;
+                ApplyProperties(canRotate, canRotate, false);
+            }
+            else if (current == DragType.Scale)
+            {
+                bool canScale = SelectedLightType != MPSLightType.Normal;
+                ApplyProperties(canScale, canScale, false);
+            }
+            else if (current == DragType.Delete)
+            {
+                ApplyProperties(!IsMain, !IsMain, false);
+            }
+            else
+            {
+                ApplyProperties(false, false, false);
+            }
         }
 
         public void SetLightType(LightType type)
         {
-            DragLight.Rotate -= OnRotate;
-            DragLight.Rotate -= OnScale;
             string name = "normal";
 
             if (type == LightType.Directional)
@@ -192,21 +204,18 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             {
                 name = "spot";
                 SelectedLightType = MPSLightType.Spot;
-                DragLight.Scale += OnScale;
-                DragLight.Rotate += OnRotate;
             }
             else
             {
                 name = "point";
                 SelectedLightType = MPSLightType.Point;
-                DragLight.Scale += OnScale;
             }
 
             this.light.type = type;
+            this.Name = IsMain ? "main" : name;
 
             SetProps();
-
-            this.Name = IsMain ? "main" : name;
+            ApplyDragType();
         }
 
         public void SetRotation(float x, float y)
@@ -262,31 +271,11 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 camera.backgroundColor = CurrentLightProperty.LightColour;
             }
         }
-
-        private void OnRotate(object sender, EventArgs args)
-        {
-            CurrentLightProperty.Rotation = this.light.transform.rotation;
-            OnTransformEvent(Rotate);
-        }
-
-        private void OnScale(object sender, EventArgs args)
-        {
-            float value = this.light.transform.localScale.x;
-            if (SelectedLightType == MPSLightType.Point) Range = value;
-            else if (SelectedLightType == MPSLightType.Spot) SpotAngle = value;
-
-            OnTransformEvent(Scale);
-        }
-
-        private void OnTransformEvent(EventHandler handler)
-        {
-            handler?.Invoke(this, EventArgs.Empty);
-        }
     }
 
     internal class LightProperty
     {
-        public static readonly Vector3 DefaultPosition = new Vector3(0f, 1.5f, 0.4f);
+        public static readonly Vector3 DefaultPosition = new Vector3(0f, 1.9f, 0.4f);
         public static readonly Quaternion DefaultRotation = Quaternion.Euler(40f, 180f, 0f);
         public Quaternion Rotation { get; set; } = DefaultRotation;
         public float Intensity { get; set; } = 0.95f;

+ 66 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/DragPoint/DragPointMeido.cs

@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    using static CustomGizmo;
+    internal abstract class DragPointMeido : DragPoint
+    {
+        protected const int jointUpper = 0;
+        protected const int jointMiddle = 1;
+        protected const int jointLower = 2;
+        protected Meido meido;
+        protected Maid maid;
+        protected bool isPlaying;
+        private bool isBone;
+        public bool IsBone
+        {
+            get => isBone;
+            set
+            {
+                if (value != isBone)
+                {
+                    isBone = value;
+                    ApplyDragType();
+                }
+            }
+        }
+
+        public virtual void Initialize(Meido meido, Func<Vector3> position, Func<Vector3> rotation)
+        {
+            base.Initialize(position, rotation);
+            this.meido = meido;
+            this.maid = meido.Maid;
+            this.isPlaying = !meido.IsStop;
+        }
+
+        public override void AddGizmo(float scale = 0.25f, GizmoMode mode = GizmoMode.Local)
+        {
+            base.AddGizmo(scale, mode);
+            Gizmo.GizmoDrag += (s, a) =>
+            {
+                meido.IsStop = true;
+                isPlaying = false;
+            };
+        }
+
+        protected override void OnMouseDown()
+        {
+            base.OnMouseDown();
+            isPlaying = !meido.IsStop;
+        }
+
+        protected void InitializeIK(TBody.IKCMO iKCmo, Transform upper, Transform middle, Transform lower)
+        {
+            iKCmo.Init(upper, middle, lower, maid.body0);
+        }
+
+        protected void Porc(TBody.IKCMO ikCmo, Transform upper, Transform middle, Transform lower)
+        {
+            IKCtrlData ikData = maid.body0.IKCtrl.GetIKData("左手");
+            ikCmo.Porc(upper, middle, lower, CursorPosition(), Vector3.zero, ikData);
+        }
+
+    }
+}

+ 42 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/DragPoint/DragPointOther.cs

@@ -0,0 +1,42 @@
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    internal class DragPointBody : DragPointGeneral
+    {
+        public bool IsCube = false;
+        protected override void ApplyDragType()
+        {
+            DragType current = CurrentDragType;
+            bool transforming = !(current == DragType.None || current == DragType.Delete);
+            ApplyProperties(transforming, IsCube && transforming, false);
+        }
+    }
+
+    internal class DragPointBG : DragPointGeneral
+    {
+        protected override void ApplyDragType()
+        {
+            ApplyProperties(Transforming, Transforming, Rotating);
+        }
+    }
+
+    internal class DragPointDogu : DragPointGeneral
+    {
+        public AttachPointInfo attachPointInfo = AttachPointInfo.Empty;
+        public string Name => MyGameObject.name;
+
+        protected override void ApplyDragType()
+        {
+            DragType current = CurrentDragType;
+            bool active = Transforming || Special;
+            ApplyProperties(active, active, Rotating);
+        }
+
+        protected override void OnDestroy()
+        {
+            GameObject.Destroy(MyGameObject);
+            base.OnDestroy();
+        }
+    }
+}

+ 2 - 3
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/BackgroundWindow2Panes/AttachPropPane.cs

@@ -5,7 +5,6 @@ using UnityEngine;
 
 namespace COM3D2.MeidoPhotoStudio.Plugin
 {
-    using static DragPointManager;
     internal class AttachPropPane : BasePane
     {
         private PropManager propManager;
@@ -188,7 +187,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         {
             if (updating || selectedMaid == this.meidoDropdown.SelectedItemIndex) return;
             selectedMaid = this.meidoDropdown.SelectedItemIndex;
-            DragDogu dragDogu = this.propManager.GetDogu(this.doguDropdown.SelectedItemIndex);
+            DragPointDogu dragDogu = this.propManager.GetDogu(this.doguDropdown.SelectedItemIndex);
             if (dragDogu != null)
             {
                 if (dragDogu.attachPointInfo.AttachPoint == AttachPoint.None) return;
@@ -199,7 +198,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private void SwitchDogu()
         {
             if (updating) return;
-            DragDogu dragDogu = this.propManager.GetDogu(this.doguDropdown.SelectedItemIndex);
+            DragPointDogu dragDogu = this.propManager.GetDogu(this.doguDropdown.SelectedItemIndex);
             if (dragDogu != null) SetAttachPointToggle(dragDogu.attachPointInfo.AttachPoint, true);
         }
 

+ 3 - 3
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/BackgroundWindowPanes/DragPointPane.cs

@@ -19,7 +19,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.header = Translation.Get("movementCube", "header");
             this.propsCubeToggle = new Toggle(Translation.Get("movementCube", "props"), PropManager.CubeActive);
             this.smallCubeToggle = new Toggle(Translation.Get("movementCube", "small"));
-            this.maidCubeToggle = new Toggle(Translation.Get("movementCube", "maid"), DragPointManager.CubeActive);
+            this.maidCubeToggle = new Toggle(Translation.Get("movementCube", "maid"), MeidoDragPointManager.CubeActive);
             this.bgCubeToggle = new Toggle(Translation.Get("movementCube", "bg"), EnvironmentManager.CubeActive);
 
             this.propsCubeToggle.ControlEvent += (s, a) =>
@@ -64,10 +64,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                     EnvironmentManager.CubeActive = value;
                     break;
                 case DragPointSetting.Maid:
-                    DragPointManager.CubeActive = value;
+                    MeidoDragPointManager.CubeActive = value;
                     break;
                 case DragPointSetting.Size:
-                    DragPointManager.CubeSmall = value;
+                    MeidoDragPointManager.CubeSmall = value;
                     EnvironmentManager.CubeSmall = value;
                     PropManager.CubeSmall = value;
                     break;

+ 4 - 4
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/BackgroundWindowPanes/LightsPane.cs

@@ -4,7 +4,7 @@ using UnityEngine;
 
 namespace COM3D2.MeidoPhotoStudio.Plugin
 {
-    using static MPSLight;
+    using static DragPointLight;
     internal class LightsPane : BasePane
     {
         private LightManager lightManager;
@@ -186,12 +186,12 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 lightType = LightType.Point;
             }
 
-            MPSLight currentLight = lightManager.CurrentLight;
+            DragPointLight currentLight = lightManager.CurrentLight;
             currentLight.SetLightType(lightType);
 
             if (lightManager.SelectedLightIndex == 0)
             {
-                this.environmentManager.BGVisible = (currentLight.SelectedLightType != MPSLightType.Normal)
+                this.environmentManager.BGVisible = (currentLight.SelectedLightType != DragPointLight.MPSLightType.Normal)
                     || !currentLight.IsColourMode;
             }
 
@@ -248,7 +248,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         public override void UpdatePane()
         {
             this.updating = true;
-            MPSLight currentLight = this.lightManager.CurrentLight;
+            DragPointLight currentLight = this.lightManager.CurrentLight;
             this.currentLightType = currentLight.SelectedLightType;
             this.lightTypeGrid.SelectedItemIndex = (int)this.currentLightType;
             this.disableToggle.Value = currentLight.IsDisabled;

+ 0 - 868
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/DragPointManager.cs

@@ -1,868 +0,0 @@
-using System;
-using System.Linq;
-using System.Collections.Generic;
-using UnityEngine;
-
-namespace COM3D2.MeidoPhotoStudio.Plugin
-{
-    using ModKey = Utility.ModKey;
-    internal class DragPointManager
-    {
-        enum IKMode
-        {
-            None, UpperLock, Mune, RotLocal, BodyTransform, FingerRotLocalY, FingerRotLocalXZ, BodySelect,
-            UpperRot
-        }
-        enum Bone
-        {
-            Head, HeadNub, ClavicleL, ClavicleR,
-            UpperArmL, UpperArmR, ForearmL, ForearmR,
-            HandL, HandR, IKHandL, IKHandR,
-            MuneL, MuneSubL, MuneR, MuneSubR,
-            Neck, Spine, Spine0a, Spine1, Spine1a, ThighL, ThighR,
-            Pelvis, Hip,
-            CalfL, CalfR, FootL, FootR,
-            // Dragpoint specific
-            Cube, Body, Torso,
-            // Fingers
-            Finger0L, Finger01L, Finger02L, Finger0NubL,
-            Finger1L, Finger11L, Finger12L, Finger1NubL,
-            Finger2L, Finger21L, Finger22L, Finger2NubL,
-            Finger3L, Finger31L, Finger32L, Finger3NubL,
-            Finger4L, Finger41L, Finger42L, Finger4NubL,
-            Finger0R, Finger01R, Finger02R, Finger0NubR,
-            Finger1R, Finger11R, Finger12R, Finger1NubR,
-            Finger2R, Finger21R, Finger22R, Finger2NubR,
-            Finger3R, Finger31R, Finger32R, Finger3NubR,
-            Finger4R, Finger41R, Finger42R, Finger4NubR,
-            // Toes
-            Toe0L, Toe01L, Toe0NubL,
-            Toe1L, Toe11L, Toe1NubL,
-            Toe2L, Toe21L, Toe2NubL,
-            Toe0R, Toe01R, Toe0NubR,
-            Toe1R, Toe11R, Toe1NubR,
-            Toe2R, Toe21R, Toe2NubR
-        }
-        public enum AttachPoint
-        {
-            None,
-            Head, Neck, UpperArmL, UpperArmR, ForearmL, ForearmR, MuneL, MuneR, HandL, HandR,
-            Pelvis, ThighL, ThighR, CalfL, CalfR, FootL, FootR
-        }
-
-        private static readonly Dictionary<AttachPoint, Bone> PointToBone = new Dictionary<AttachPoint, Bone>()
-        {
-            [AttachPoint.Head] = Bone.Head,
-            [AttachPoint.Neck] = Bone.HeadNub,
-            [AttachPoint.UpperArmL] = Bone.UpperArmL,
-            [AttachPoint.UpperArmR] = Bone.UpperArmR,
-            [AttachPoint.ForearmL] = Bone.ForearmL,
-            [AttachPoint.ForearmR] = Bone.ForearmR,
-            [AttachPoint.MuneL] = Bone.MuneL,
-            [AttachPoint.MuneR] = Bone.MuneR,
-            [AttachPoint.HandL] = Bone.HandL,
-            [AttachPoint.HandR] = Bone.HandR,
-            [AttachPoint.Pelvis] = Bone.Pelvis,
-            [AttachPoint.ThighL] = Bone.ThighL,
-            [AttachPoint.ThighR] = Bone.ThighR,
-            [AttachPoint.CalfL] = Bone.CalfL,
-            [AttachPoint.CalfR] = Bone.CalfR,
-            [AttachPoint.FootL] = Bone.FootL,
-            [AttachPoint.FootR] = Bone.FootR,
-        };
-
-
-        private static readonly Dictionary<IKMode, Bone[]> IKGroup = new Dictionary<IKMode, Bone[]>()
-        {
-            [IKMode.None] = new[]
-            {
-                Bone.UpperArmL, Bone.ForearmL, Bone.HandL, Bone.UpperArmR,
-                Bone.ForearmR, Bone.HandR, Bone.CalfL, Bone.FootL, Bone.CalfR, Bone.FootR
-            },
-            [IKMode.UpperLock] = new[] { Bone.HandL, Bone.HandR, Bone.FootL, Bone.FootR },
-            [IKMode.Mune] = new[] { Bone.Head, Bone.MuneL, Bone.MuneR },
-            [IKMode.RotLocal] = new[]
-            {
-                Bone.Head, Bone.CalfL, Bone.CalfR, Bone.Torso,
-                Bone.Pelvis, Bone.HandL, Bone.HandR, Bone.FootL, Bone.FootR
-            },
-            [IKMode.BodyTransform] = new[] { Bone.Body, Bone.Cube },
-            [IKMode.BodySelect] = new[] { Bone.Head, Bone.Body },
-            [IKMode.FingerRotLocalXZ] = new[]
-            {
-                Bone.Finger01L, Bone.Finger02L, Bone.Finger0NubL,
-                Bone.Finger11L, Bone.Finger12L, Bone.Finger1NubL,
-                Bone.Finger21L, Bone.Finger22L, Bone.Finger2NubL,
-                Bone.Finger31L, Bone.Finger32L, Bone.Finger3NubL,
-                Bone.Finger41L, Bone.Finger42L, Bone.Finger4NubL,
-                Bone.Finger01R, Bone.Finger02R, Bone.Finger0NubR,
-                Bone.Finger11R, Bone.Finger12R, Bone.Finger1NubR,
-                Bone.Finger21R, Bone.Finger22R, Bone.Finger2NubR,
-                Bone.Finger31R, Bone.Finger32R, Bone.Finger3NubR,
-                Bone.Finger41R, Bone.Finger42R, Bone.Finger4NubR,
-                Bone.Toe01L, Bone.Toe0NubL, Bone.Toe11L, Bone.Toe1NubL,
-                Bone.Toe21L, Bone.Toe2NubL, Bone.Toe01R, Bone.Toe0NubR,
-                Bone.Toe11R, Bone.Toe1NubR, Bone.Toe21R, Bone.Toe2NubR
-            },
-            [IKMode.FingerRotLocalY] = new[] {
-                Bone.Finger01L, Bone.Finger11L, Bone.Finger21L, Bone.Finger31L, Bone.Finger41L,
-                Bone.Finger01R, Bone.Finger11R, Bone.Finger21R, Bone.Finger31R, Bone.Finger41R,
-                Bone.Toe01L, Bone.Toe11L, Bone.Toe21L, Bone.Toe01R, Bone.Toe11R, Bone.Toe21R
-            }
-        };
-        private static readonly Dictionary<IKMode, DragInfo[]> IKGroupBone = new Dictionary<IKMode, DragInfo[]>()
-        {
-            [IKMode.None] = new[] {
-                DragInfo.DragBone(Bone.UpperArmL), DragInfo.DragBone(Bone.ForearmL), DragInfo.DragBone(Bone.HandL),
-                DragInfo.DragBone(Bone.UpperArmR), DragInfo.DragBone(Bone.ForearmR), DragInfo.DragBone(Bone.HandR),
-                DragInfo.DragBone(Bone.CalfL), DragInfo.DragBone(Bone.FootL), DragInfo.DragBone(Bone.CalfR),
-                DragInfo.DragBone(Bone.FootR), DragInfo.DragBone(Bone.Neck), DragInfo.DragBone(Bone.Spine1a),
-                DragInfo.DragBone(Bone.Spine1), DragInfo.DragBone(Bone.Spine0a), DragInfo.DragBone(Bone.Spine),
-                DragInfo.DragBone(Bone.Hip)
-            },
-            [IKMode.UpperLock] = new[] {
-                DragInfo.Gizmo(Bone.Neck), DragInfo.Gizmo(Bone.Spine1a), DragInfo.Gizmo(Bone.Spine1),
-                DragInfo.Gizmo(Bone.Spine0a), DragInfo.Gizmo(Bone.Spine), DragInfo.DragBone(Bone.Hip),
-                DragInfo.DragBone(Bone.HandR), DragInfo.DragBone(Bone.HandL), DragInfo.DragBone(Bone.FootL),
-                DragInfo.DragBone(Bone.FootR)
-            },
-            [IKMode.RotLocal] = new[] {
-                DragInfo.Gizmo(Bone.HandL), DragInfo.Gizmo(Bone.HandR), DragInfo.Gizmo(Bone.FootL),
-                DragInfo.Gizmo(Bone.FootR), DragInfo.Gizmo(Bone.Hip)
-            },
-            [IKMode.Mune] = new[] {
-                DragInfo.Gizmo(Bone.ForearmL), DragInfo.Gizmo(Bone.ForearmR), DragInfo.Gizmo(Bone.CalfL),
-                DragInfo.Gizmo(Bone.CalfR), DragInfo.Drag(Bone.MuneL), DragInfo.Drag(Bone.MuneR),
-                DragInfo.Drag(Bone.Head)
-            },
-            [IKMode.UpperRot] = new[] {
-                DragInfo.Gizmo(Bone.UpperArmL), DragInfo.Gizmo(Bone.UpperArmR), DragInfo.Gizmo(Bone.ThighL),
-                DragInfo.Gizmo(Bone.ThighR)
-            },
-            [IKMode.BodyTransform] = new[] { DragInfo.Drag(Bone.Body), DragInfo.DragAll(Bone.Cube) },
-            [IKMode.BodySelect] = new[] { DragInfo.Drag(Bone.Head), DragInfo.Drag(Bone.Body) },
-            [IKMode.FingerRotLocalXZ] = IKGroup[IKMode.FingerRotLocalXZ]
-                .Select(bone => DragInfo.DragBone(bone)).ToArray(),
-            [IKMode.FingerRotLocalY] = IKGroup[IKMode.FingerRotLocalY]
-                .Select(bone => DragInfo.DragBone(bone)).ToArray()
-        };
-        private static bool cubeActive = false;
-        public static bool CubeActive
-        {
-            get => cubeActive;
-            set
-            {
-                if (value != cubeActive)
-                {
-                    cubeActive = value;
-                    CubeActiveChange?.Invoke(null, EventArgs.Empty);
-                }
-            }
-        }
-        private static bool cubeSmall = false;
-        public static bool CubeSmall
-        {
-            get => cubeSmall;
-            set
-            {
-                if (value != cubeSmall)
-                {
-                    cubeSmall = value;
-                    CubeSmallChange?.Invoke(null, EventArgs.Empty);
-                }
-            }
-        }
-        private static event EventHandler CubeActiveChange;
-        private static event EventHandler CubeSmallChange;
-        private Meido meido;
-        private Maid maid;
-        private Dictionary<Bone, BaseDrag> DragPoint;
-        private Dictionary<Bone, Transform> BoneTransform;
-        private IKMode ikMode;
-        private IKMode ikModeOld = IKMode.None;
-        public event EventHandler<MeidoUpdateEventArgs> SelectMaid;
-        private bool active = false;
-        public bool Active
-        {
-            get => active;
-            set
-            {
-                if (this.active == value) return;
-                this.active = value;
-                this.SetActive(this.active);
-            }
-        }
-        private bool isBone = false;
-        public bool IsBone
-        {
-            get => isBone;
-            set
-            {
-                if (this.isBone == value) return;
-                this.isBone = value;
-                this.SetBoneMode(this.isBone);
-            }
-        }
-
-        public DragPointManager(Meido meido)
-        {
-            this.meido = meido;
-            this.maid = meido.Maid;
-            this.meido.BodyLoad += Initialize;
-        }
-
-        public void Destroy()
-        {
-            foreach (KeyValuePair<Bone, BaseDrag> dragPoint in DragPoint)
-            {
-                GameObject.Destroy(dragPoint.Value.gameObject);
-            }
-            BoneTransform.Clear();
-            DragPoint.Clear();
-            CubeSmallChange -= OnCubeSmall;
-            CubeActiveChange -= OnCubeSmall;
-        }
-
-        public void Update()
-        {
-            if (Input.GetKey(KeyCode.Z) || Input.GetKey(KeyCode.X) || Input.GetKey(KeyCode.C))
-            {
-                ikMode = IKMode.BodyTransform;
-            }
-            else if (Input.GetKey(KeyCode.A))
-            {
-                ikMode = IKMode.BodySelect;
-            }
-            else if (Utility.GetModKey(ModKey.Control) && Utility.GetModKey(ModKey.Alt))
-            {
-                ikMode = IKMode.Mune;
-            }
-            else if (Utility.GetModKey(ModKey.Shift) && Input.GetKey(KeyCode.Space))
-            {
-                ikMode = IKMode.FingerRotLocalY;
-            }
-            else if (Utility.GetModKey(ModKey.Alt))
-            {
-                bool shift = IsBone && Utility.GetModKey(ModKey.Shift);
-                ikMode = shift ? IKMode.UpperRot : IKMode.RotLocal;
-            }
-            else if (Input.GetKey(KeyCode.Space))
-            {
-                ikMode = IKMode.FingerRotLocalXZ;
-            }
-            else if (Utility.GetModKey(ModKey.Control))
-            {
-                ikMode = IKMode.UpperLock;
-            }
-            else
-            {
-                ikMode = IKMode.None;
-            }
-
-            if (ikMode != ikModeOld) UpdateIK();
-
-            ikModeOld = ikMode;
-        }
-
-        public Transform GetAttachPointTransform(AttachPoint point)
-        {
-            if (point == AttachPoint.None) return null;
-            return BoneTransform[PointToBone[point]];
-        }
-
-        private void Initialize(object sender, EventArgs args)
-        {
-            meido.BodyLoad -= Initialize;
-            InitializeBones();
-            InitializeDragPoints();
-            this.Active = true;
-            this.SetBoneMode(false);
-            CubeSmallChange += OnCubeSmall;
-            CubeActiveChange += OnCubeActive;
-        }
-
-        private void SetBoneMode(bool active)
-        {
-            foreach (KeyValuePair<Bone, BaseDrag> dragPoint in DragPoint)
-            {
-                dragPoint.Value.IsBone = this.IsBone;
-                if (!this.IsBone)
-                {
-                    dragPoint.Value.SetDragProp(false, true, dragPoint.Key >= Bone.Finger0L);
-                }
-            }
-            UpdateIK();
-        }
-
-        private void SetActive(bool active)
-        {
-            if (active)
-            {
-                ikMode = ikModeOld = IKMode.None;
-                ((DragHead)DragPoint[Bone.Head]).IsIK = true;
-                UpdateIK();
-            }
-            else
-            {
-                foreach (KeyValuePair<Bone, BaseDrag> dragPoint in DragPoint)
-                {
-                    dragPoint.Value.gameObject.SetActive(false);
-                }
-                ((DragHead)DragPoint[Bone.Head]).IsIK = false;
-                DragPoint[Bone.Head].SetDragProp(false, true, false);
-                DragPoint[Bone.Body].SetDragProp(false, true, false);
-                DragPoint[Bone.Cube].SetDragProp(false, true, true);
-            }
-        }
-
-        private void UpdateIK()
-        {
-            if (this.Active)
-            {
-                if (this.IsBone) UpdateBoneIK();
-                else
-                {
-                    foreach (KeyValuePair<Bone, BaseDrag> dragPoint in DragPoint)
-                    {
-                        dragPoint.Value.gameObject.SetActive(false);
-                    }
-
-                    foreach (Bone bone in IKGroup[ikMode])
-                    {
-                        DragPoint[bone].gameObject.SetActive(true);
-                    }
-                }
-
-                bool cubeVisible = CubeActive && (ikMode == IKMode.BodyTransform);
-                DragPoint[Bone.Cube].SetDragProp(cubeVisible, cubeVisible, cubeVisible);
-                DragPoint[Bone.Cube].gameObject.SetActive(cubeVisible);
-            }
-            else
-            {
-                if (ikMode == IKMode.BodySelect)
-                {
-                    DragPoint[Bone.Body].gameObject.SetActive(true);
-                    DragPoint[Bone.Head].gameObject.SetActive(true);
-                }
-                else if (ikMode == IKMode.BodyTransform)
-                {
-                    DragPoint[Bone.Body].gameObject.SetActive(true);
-                    DragPoint[Bone.Cube].gameObject.SetActive(CubeActive);
-                }
-                else if (ikMode == IKMode.UpperRot || ikMode == IKMode.RotLocal)
-                {
-                    DragPoint[Bone.Head].gameObject.SetActive(true);
-                }
-                else
-                {
-                    DragPoint[Bone.Body].gameObject.SetActive(false);
-                    DragPoint[Bone.Head].gameObject.SetActive(false);
-                    DragPoint[Bone.Cube].gameObject.SetActive(false);
-                }
-            }
-        }
-
-        private void UpdateBoneIK()
-        {
-            foreach (KeyValuePair<Bone, BaseDrag> dragPoint in DragPoint)
-            {
-                dragPoint.Value.gameObject.SetActive(false);
-                dragPoint.Value.SetDragProp(false, false, dragPoint.Key >= Bone.Finger0L);
-            }
-
-            foreach (DragInfo info in IKGroupBone[ikMode])
-            {
-                BaseDrag drag = DragPoint[info.Bone];
-                drag.gameObject.SetActive(true);
-                drag.SetDragProp(info.GizmoActive, info.DragPointActive, info.DragPointVisible);
-            }
-        }
-
-        private void OnCubeSmall(object sender, EventArgs args)
-        {
-            DragBody dragPoint = (DragBody)DragPoint[Bone.Cube];
-            dragPoint.DragPointScale = CubeSmall ? 0.4f : 1f;
-        }
-
-        private void OnCubeActive(object sender, EventArgs args)
-        {
-            DragPoint[Bone.Cube].SetDragProp(CubeActive, CubeActive, CubeActive);
-            DragPoint[Bone.Cube].gameObject.SetActive(CubeActive);
-        }
-
-        private void OnSelectFace(object sender, EventArgs args)
-        {
-            OnMeidoSelect(new MeidoUpdateEventArgs(meido.ActiveSlot, true, false));
-        }
-
-        private void OnSelectBody(object sender, EventArgs args)
-        {
-            OnMeidoSelect(new MeidoUpdateEventArgs(meido.ActiveSlot, true, true));
-        }
-
-        private void OnSetDragPointScale(object sender, EventArgs args)
-        {
-            this.SetDragPointScale(maid.transform.localScale.x);
-        }
-
-        private void OnMeidoSelect(MeidoUpdateEventArgs args)
-        {
-            SelectMaid?.Invoke(this, args);
-        }
-
-        private void SetDragPointScale(float scale)
-        {
-            foreach (KeyValuePair<Bone, BaseDrag> kvp in DragPoint)
-            {
-                if (kvp.Key == Bone.Cube) continue;
-                BaseDrag dragPoint = kvp.Value;
-                dragPoint.DragPointScale = scale;
-            }
-        }
-
-        // TODO: Rework this a little to reduce number of needed BaseDrag derived components
-        private void InitializeDragPoints()
-        {
-            DragPoint = new Dictionary<Bone, BaseDrag>();
-
-            Vector3 limbDragPointSize = Vector3.one * 0.12f;
-            Vector3 limbDragPointSizeBone = Vector3.one * 0.07f;
-            Vector3 fingerDragPointSize = Vector3.one * 0.015f;
-
-            Func<Transform[], Transform[], Transform[], bool, BaseDrag[]> MakeIKChainDragPoint =
-                (upper, middle, lower, leg) =>
-            {
-                GameObject[] dragPoints = new GameObject[3];
-                for (int i = 0; i < dragPoints.Length; i++)
-                {
-                    dragPoints[i] =
-                         BaseDrag.MakeDragPoint(PrimitiveType.Sphere, limbDragPointSize, BaseDrag.LightBlue);
-                }
-
-                return new BaseDrag[3] {
-                    dragPoints[0].AddComponent<DragJointForearm>()
-                        .Initialize(upper, false, meido, () => upper[2].position, () => Vector3.zero),
-                    dragPoints[1].AddComponent<DragJointForearm>()
-                        .Initialize(middle, leg, meido, () => middle[2].position, () => Vector3.zero),
-                    dragPoints[2].AddComponent<DragJointHand>()
-                        .Initialize(lower, leg, meido, () => lower[2].position, () => Vector3.zero)
-                };
-            };
-
-            // TODO: Modify dragpoint sizes for each joint
-            Action<Bone, Bone, int> MakeFingerDragPoint = (start, end, joints) =>
-            {
-                for (Bone it = start; it <= end; it += joints)
-                {
-                    for (int i = 0; i < joints - 1; i++)
-                    {
-                        Bone bone = it + 1 + i;
-                        DragPoint[bone] = BaseDrag.MakeDragPoint(PrimitiveType.Sphere, fingerDragPointSize, BaseDrag.Blue)
-                            .AddComponent<DragJointFinger>()
-                            .Initialize(new Transform[3] {
-                                BoneTransform[bone - 1],
-                                BoneTransform[bone - 1],
-                                BoneTransform[bone]
-                                }, i == 0, meido, () => BoneTransform[bone].position, () => Vector3.zero
-                            );
-                        DragPoint[bone].gameObject.layer = 0;
-                        DragPoint[bone].DragPointVisible = true;
-                    }
-                }
-            };
-
-            // Cube Dragpoint
-            DragPoint[Bone.Cube] = BaseDrag.MakeDragPoint<DragBody>(
-                PrimitiveType.Cube, Vector3.one * 0.12f, BaseDrag.Blue
-            ).Initialize(meido,
-                () => maid.transform.position,
-                () => Vector3.zero
-            );
-            DragBody dragCube = (DragBody)DragPoint[Bone.Cube];
-            dragCube.Scale += OnSetDragPointScale;
-            dragCube.DragPointVisible = true;
-            // TODO: Make gizmos work on cube
-
-            // Body Dragpoint
-            DragPoint[Bone.Body] = BaseDrag.MakeDragPoint<DragBody>(
-                PrimitiveType.Capsule, new Vector3(0.2f, 0.3f, 0.24f), BaseDrag.LightBlue
-            ).Initialize(meido,
-                () => new Vector3(
-                    (BoneTransform[Bone.Hip].position.x + BoneTransform[Bone.Spine0a].position.x) / 2f,
-                    (BoneTransform[Bone.Spine1].position.y + BoneTransform[Bone.Spine0a].position.y) / 2f,
-                    (BoneTransform[Bone.Spine0a].position.z + BoneTransform[Bone.Hip].position.z) / 2f
-                ),
-                () => new Vector3(
-                    BoneTransform[Bone.Spine0a].transform.eulerAngles.x,
-                    BoneTransform[Bone.Spine0a].transform.eulerAngles.y,
-                    BoneTransform[Bone.Spine0a].transform.eulerAngles.z + 90f
-                )
-            );
-            DragBody dragBody = (DragBody)DragPoint[Bone.Body];
-            dragBody.Select += OnSelectBody;
-            dragBody.Scale += OnSetDragPointScale;
-
-            // Head Dragpoint
-            DragPoint[Bone.Head] = BaseDrag.MakeDragPoint<DragHead>(
-                PrimitiveType.Sphere, new Vector3(0.2f, 0.24f, 0.2f), BaseDrag.LightBlue
-            ).Initialize(BoneTransform[Bone.Neck], meido,
-                () => new Vector3(
-                    BoneTransform[Bone.Head].position.x,
-                    (BoneTransform[Bone.Head].position.y * 1.2f + BoneTransform[Bone.HeadNub].position.y * 0.8f) / 2f,
-                    BoneTransform[Bone.Head].position.z
-                ),
-                () => new Vector3(
-                    BoneTransform[Bone.Head].eulerAngles.x,
-                    BoneTransform[Bone.Head].eulerAngles.y,
-                    BoneTransform[Bone.Head].eulerAngles.z + 90f
-                )
-            );
-            DragHead dragHead = (DragHead)DragPoint[Bone.Head];
-            dragHead.Select += OnSelectFace;
-
-            // Torso Dragpoint
-            DragPoint[Bone.Torso] = BaseDrag.MakeDragPoint<DragTorso>(
-                PrimitiveType.Capsule, new Vector3(0.2f, 0.19f, 0.24f), BaseDrag.LightBlue
-            );
-            Transform spineTrans1 = BoneTransform[Bone.Spine1];
-            Transform spineTrans2 = BoneTransform[Bone.Spine1a];
-            Transform[] spineParts = new Transform[4] {
-                BoneTransform[Bone.Spine1a],
-                BoneTransform[Bone.Spine1],
-                BoneTransform[Bone.Spine0a],
-                BoneTransform[Bone.Spine]
-            };
-            DragTorso dragTorso = (DragTorso)DragPoint[Bone.Torso];
-            dragTorso.Initialize(spineParts, meido,
-                () => new Vector3(
-                    spineTrans1.position.x,
-                    (spineTrans2.position.y * 2f) / 2f,
-                    spineTrans1.position.z
-                ),
-                () => new Vector3(
-                    spineTrans1.eulerAngles.x,
-                    spineTrans1.eulerAngles.y,
-                    spineTrans1.eulerAngles.z + 90f
-                )
-            );
-
-            // Pelvis Dragpoint
-            DragPoint[Bone.Pelvis] = BaseDrag.MakeDragPoint<DragPelvis>(
-                PrimitiveType.Capsule, new Vector3(0.2f, 0.15f, 0.24f), BaseDrag.LightBlue
-            );
-            Transform pelvisTrans = BoneTransform[Bone.Pelvis];
-            Transform spineTrans = BoneTransform[Bone.Spine];
-            DragPelvis dragPelvis = (DragPelvis)DragPoint[Bone.Pelvis];
-            dragPelvis.Initialize(BoneTransform[Bone.Pelvis], meido,
-                () => new Vector3(
-                    pelvisTrans.position.x,
-                    (pelvisTrans.position.y + spineTrans.position.y) / 2f,
-                    pelvisTrans.position.z
-                ),
-                () => new Vector3(
-                    pelvisTrans.eulerAngles.x + 90f,
-                    pelvisTrans.eulerAngles.y + 90f,
-                    pelvisTrans.eulerAngles.z
-                )
-            );
-
-            // Left Mune Dragpoint
-            DragPoint[Bone.MuneL] = BaseDrag.MakeDragPoint<DragMune>(
-                PrimitiveType.Sphere, Vector3.one * 0.12f, BaseDrag.LightBlue
-            );
-            Transform[] muneIKChainL = new Transform[3] {
-                BoneTransform[Bone.MuneL],
-                BoneTransform[Bone.MuneL],
-                BoneTransform[Bone.MuneSubL]
-            };
-            DragMune dragMuneL = (DragMune)DragPoint[Bone.MuneL];
-            dragMuneL.Initialize(muneIKChainL, meido,
-                () => (BoneTransform[Bone.MuneL].position + BoneTransform[Bone.MuneSubL].position) / 2f,
-                () => Vector3.zero
-            );
-
-            // Right Mune Dragpoint
-            DragPoint[Bone.MuneR] = BaseDrag.MakeDragPoint<DragMune>(
-                PrimitiveType.Sphere, Vector3.one * 0.12f, BaseDrag.LightBlue
-            );
-            Transform[] muneIKChainR = new Transform[3] {
-                BoneTransform[Bone.MuneR],
-                BoneTransform[Bone.MuneR],
-                BoneTransform[Bone.MuneSubR]
-            };
-            DragMune dragMuneR = (DragMune)DragPoint[Bone.MuneR];
-            dragMuneR.Initialize(muneIKChainR, meido,
-                () => (BoneTransform[Bone.MuneR].position + BoneTransform[Bone.MuneSubR].position) / 2f,
-                () => Vector3.zero
-            );
-
-            // Left Arm Dragpoint
-            BaseDrag[] ikChainArmL = MakeIKChainDragPoint(
-                new Transform[3] {
-                    BoneTransform[Bone.ClavicleL],
-                    BoneTransform[Bone.ClavicleL],
-                    BoneTransform[Bone.UpperArmL]
-                },
-                new Transform[3] {
-                    BoneTransform[Bone.UpperArmL],
-                    BoneTransform[Bone.UpperArmL],
-                    BoneTransform[Bone.ForearmL]
-                },
-                new Transform[3] {
-                    BoneTransform[Bone.UpperArmL],
-                    BoneTransform[Bone.ForearmL],
-                    BoneTransform[Bone.HandL]
-                },
-                false
-            );
-            DragPoint[Bone.UpperArmL] = ikChainArmL[0];
-            DragPoint[Bone.ForearmL] = ikChainArmL[1];
-            DragPoint[Bone.HandL] = ikChainArmL[2];
-
-            // Right Arm Dragpoint
-            BaseDrag[] ikChainArmR = MakeIKChainDragPoint(
-                new Transform[3] {
-                    BoneTransform[Bone.ClavicleR],
-                    BoneTransform[Bone.ClavicleR],
-                    BoneTransform[Bone.UpperArmR]
-                },
-                new Transform[3] {
-                    BoneTransform[Bone.UpperArmR],
-                    BoneTransform[Bone.UpperArmR],
-                    BoneTransform[Bone.ForearmR]
-                },
-                new Transform[3] {
-                    BoneTransform[Bone.UpperArmR],
-                    BoneTransform[Bone.ForearmR],
-                    BoneTransform[Bone.HandR]
-                },
-                false
-            );
-            DragPoint[Bone.UpperArmR] = ikChainArmR[0];
-            DragPoint[Bone.ForearmR] = ikChainArmR[1];
-            DragPoint[Bone.HandR] = ikChainArmR[2];
-
-            // Left Leg Dragpoint
-            BaseDrag[] ikChainLegL = MakeIKChainDragPoint(
-                new Transform[3] {
-                    BoneTransform[Bone.ThighL],
-                    BoneTransform[Bone.CalfL],
-                    BoneTransform[Bone.FootL]
-                },
-                new Transform[3] {
-                    BoneTransform[Bone.ThighL],
-                    BoneTransform[Bone.ThighL],
-                    BoneTransform[Bone.CalfL]
-                },
-                new Transform[3] {
-                    BoneTransform[Bone.ThighL],
-                    BoneTransform[Bone.CalfL],
-                    BoneTransform[Bone.FootL]
-                },
-                true
-            );
-            DragPoint[Bone.CalfL] = ikChainLegL[1];
-            DragPoint[Bone.FootL] = ikChainLegL[2];
-
-            // Right Arm Dragpoint
-            BaseDrag[] ikChainLegR = MakeIKChainDragPoint(
-                new Transform[3] {
-                    BoneTransform[Bone.ThighR],
-                    BoneTransform[Bone.CalfR],
-                    BoneTransform[Bone.FootR]
-                },
-                new Transform[3] {
-                    BoneTransform[Bone.ThighR],
-                    BoneTransform[Bone.ThighR],
-                    BoneTransform[Bone.CalfR]
-                },
-                new Transform[3] {
-                    BoneTransform[Bone.ThighR],
-                    BoneTransform[Bone.CalfR],
-                    BoneTransform[Bone.FootR]
-                },
-                true
-            );
-            DragPoint[Bone.CalfR] = ikChainLegR[1];
-            DragPoint[Bone.FootR] = ikChainLegR[2];
-
-            // destroy unused thigh dragpoints 
-            GameObject.Destroy(ikChainLegL[0].gameObject);
-            GameObject.Destroy(ikChainLegR[0].gameObject);
-
-            // Spine Dragpoints
-            for (Bone bone = Bone.Neck; bone <= Bone.ThighR; ++bone)
-            {
-                Transform pos = BoneTransform[bone];
-                DragPoint[bone] = BaseDrag.MakeDragPoint<DragSpine>(
-                    PrimitiveType.Sphere, Vector3.one * 0.04f, BaseDrag.LightBlue
-                ).Initialize(BoneTransform[bone], false, meido,
-                    () => pos.position,
-                    () => Vector3.zero
-                );
-            }
-
-            // Hip DragPoint
-            DragPoint[Bone.Hip] = BaseDrag.MakeDragPoint<DragSpine>(
-                PrimitiveType.Cube, Vector3.one * 0.045f, BaseDrag.LightBlue
-            ).Initialize(BoneTransform[Bone.Hip], true, meido,
-                () => BoneTransform[Bone.Hip].position,
-                () => Vector3.zero
-            );
-
-            MakeFingerDragPoint(Bone.Finger0L, Bone.Finger4R, 4);
-            MakeFingerDragPoint(Bone.Toe0L, Bone.Toe2R, 3);
-        }
-
-        private void InitializeBones()
-        {
-            BoneTransform = new Dictionary<Bone, Transform>()
-            {
-                [Bone.Head] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 Head", true),
-                [Bone.Neck] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 Neck", true),
-                [Bone.HeadNub] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 HeadNub", true),
-                [Bone.IKHandL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "_IK_handL", true),
-                [Bone.IKHandR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "_IK_handR", true),
-                [Bone.MuneL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Mune_L", true),
-                [Bone.MuneSubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Mune_L_sub", true),
-                [Bone.MuneR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Mune_R", true),
-                [Bone.MuneSubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Mune_R_sub", true),
-                [Bone.Pelvis] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 Pelvis", true),
-                [Bone.Hip] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01", true),
-                [Bone.Spine] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 Spine", true),
-                [Bone.Spine0a] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 Spine0a", true),
-                [Bone.Spine1] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 Spine1", true),
-                [Bone.Spine1a] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 Spine1a", true),
-                [Bone.ClavicleL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Clavicle", true),
-                [Bone.ClavicleR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Clavicle", true),
-                [Bone.UpperArmL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L UpperArm", true),
-                [Bone.ForearmL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Forearm", true),
-                [Bone.HandL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Hand", true),
-                [Bone.UpperArmR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R UpperArm", true),
-                [Bone.ForearmR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Forearm", true),
-                [Bone.HandR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Hand", true),
-                [Bone.ThighL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Thigh", true),
-                [Bone.CalfL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Calf", true),
-                [Bone.FootL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Foot", true),
-                [Bone.ThighR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Thigh", true),
-                [Bone.CalfR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Calf", true),
-                [Bone.FootR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Foot", true),
-                // fingers
-                [Bone.Finger0L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger0", true),
-                [Bone.Finger01L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger01", true),
-                [Bone.Finger02L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger02", true),
-                [Bone.Finger0NubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger0Nub", true),
-                [Bone.Finger1L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger1", true),
-                [Bone.Finger11L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger11", true),
-                [Bone.Finger12L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger12", true),
-                [Bone.Finger1NubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger1Nub", true),
-                [Bone.Finger2L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger2", true),
-                [Bone.Finger21L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger21", true),
-                [Bone.Finger22L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger22", true),
-                [Bone.Finger2NubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger2Nub", true),
-                [Bone.Finger3L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger3", true),
-                [Bone.Finger31L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger31", true),
-                [Bone.Finger32L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger32", true),
-                [Bone.Finger3NubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger3Nub", true),
-                [Bone.Finger4L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger4", true),
-                [Bone.Finger41L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger41", true),
-                [Bone.Finger42L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger42", true),
-                [Bone.Finger4NubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger4Nub", true),
-                [Bone.Finger0R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger0", true),
-                [Bone.Finger01R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger01", true),
-                [Bone.Finger02R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger02", true),
-                [Bone.Finger0NubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger0Nub", true),
-                [Bone.Finger1R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger1", true),
-                [Bone.Finger11R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger11", true),
-                [Bone.Finger12R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger12", true),
-                [Bone.Finger1NubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger1Nub", true),
-                [Bone.Finger2R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger2", true),
-                [Bone.Finger21R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger21", true),
-                [Bone.Finger22R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger22", true),
-                [Bone.Finger2NubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger2Nub", true),
-                [Bone.Finger3R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger3", true),
-                [Bone.Finger31R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger31", true),
-                [Bone.Finger32R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger32", true),
-                [Bone.Finger3NubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger3Nub", true),
-                [Bone.Finger4R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger4", true),
-                [Bone.Finger41R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger41", true),
-                [Bone.Finger42R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger42", true),
-                [Bone.Finger4NubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger4Nub", true),
-                // Toes
-                [Bone.Toe0L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe0", true),
-                [Bone.Toe01L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe01", true),
-                [Bone.Toe0NubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe0Nub", true),
-                [Bone.Toe1L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe1", true),
-                [Bone.Toe11L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe11", true),
-                [Bone.Toe1NubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe1Nub", true),
-                [Bone.Toe2L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe2", true),
-                [Bone.Toe21L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe21", true),
-                [Bone.Toe2NubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe2Nub", true),
-                [Bone.Toe0R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe0", true),
-                [Bone.Toe01R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe01", true),
-                [Bone.Toe0NubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe0Nub", true),
-                [Bone.Toe1R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe1", true),
-                [Bone.Toe11R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe11", true),
-                [Bone.Toe1NubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe1Nub", true),
-                [Bone.Toe2R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe2", true),
-                [Bone.Toe21R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe21", true),
-                [Bone.Toe2NubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe2Nub", true)
-            };
-        }
-
-        private struct DragInfo
-        {
-            public Bone Bone { get; }
-            public bool GizmoActive { get; }
-            public bool DragPointActive { get; }
-            public bool DragPointVisible { get; }
-
-            public DragInfo(Bone bone, bool gizmoActive, bool dragPointActive, bool dragPointVisible)
-            {
-                this.Bone = bone;
-                this.GizmoActive = gizmoActive;
-                this.DragPointActive = dragPointActive;
-                this.DragPointVisible = dragPointVisible;
-            }
-
-            public static DragInfo Gizmo(Bone bone)
-            {
-                return new DragInfo(bone, true, false, false);
-            }
-
-            public static DragInfo Drag(Bone bone)
-            {
-                return new DragInfo(bone, false, true, false);
-            }
-
-            public static DragInfo DragBone(Bone bone)
-            {
-                return new DragInfo(bone, false, true, true);
-            }
-
-            public static DragInfo DragAll(Bone bone)
-            {
-                return new DragInfo(bone, true, true, true);
-            }
-        }
-
-        public struct AttachPointInfo
-        {
-            public DragPointManager.AttachPoint AttachPoint { get; }
-            public string MaidGuid { get; }
-            public int MaidIndex { get; }
-            public static AttachPointInfo Empty
-            {
-                get => new AttachPointInfo(DragPointManager.AttachPoint.None, String.Empty, -1);
-            }
-
-            public AttachPointInfo(DragPointManager.AttachPoint attachPoint, string maidGuid, int maidIndex)
-            {
-                this.AttachPoint = attachPoint;
-                this.MaidGuid = maidGuid;
-                this.MaidIndex = maidIndex;
-            }
-
-        }
-    }
-}

+ 17 - 28
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/EnvironmentManager.cs

@@ -38,7 +38,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private GameObject bgObject;
         private Transform bg;
         private CameraInfo cameraInfo;
-        private DragDogu bgDragPoint;
+        private DragPointBG bgDragPoint;
         public LightManager LightManager { get; }
         public PropManager PropManager { get; }
         public EffectManager EffectManager { get; }
@@ -52,8 +52,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 bgObject.SetActive(this.bgVisible);
             }
         }
-        private DragType currentDragType = DragType.None;
-        private DragType dragTypeOld = DragType.None;
         private enum DragType
         {
             None, Transform
@@ -71,11 +69,14 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             bgObject = GameObject.Find("__GameMain__/BG");
             bg = bgObject.transform;
 
-            bgDragPoint = BaseDrag.MakeDragPoint<DragDogu>(
-                PrimitiveType.Cube, Vector3.one * 0.12f, BaseDrag.LightBlue
-            ).Initialize(bgObject, true);
-            bgDragPoint.SetDragProp(false, false, false);
-            bgDragPoint.DragPointScale = CubeSmall ? 0.4f : 1f;
+            bgDragPoint = DragPoint.Make<DragPointBG>(
+                PrimitiveType.Cube, Vector3.one * 0.12f, DragPoint.LightBlue
+            );
+            bgDragPoint.Initialize(() => bg.position, () => Vector3.zero);
+            bgDragPoint.Set(bg);
+            bgDragPoint.AddGizmo();
+            bgDragPoint.ConstantScale = true;
+            bgDragPoint.gameObject.SetActive(CubeActive);
 
             cameraObject = new GameObject("subCamera");
             subCamera = cameraObject.AddComponent<Camera>();
@@ -102,6 +103,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             EffectManager.Activate();
 
             CubeSmallChange += OnCubeSmall;
+            CubeActiveChange += OnCubeActive;
         }
 
         public void Deactivate()
@@ -130,6 +132,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             GameMain.Instance.MainCamera.SetDistance(1.6f, true);
             GameMain.Instance.MainCamera.SetAroundAngle(new Vector2(245.5691f, 6.273283f), true);
             CubeSmallChange -= OnCubeSmall;
+            CubeActiveChange -= OnCubeActive;
         }
 
         public void Update()
@@ -152,25 +155,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 }
             }
 
-            if (CubeActive && (Input.GetKey(KeyCode.Z) || Input.GetKey(KeyCode.X) || Input.GetKey(KeyCode.C)))
-            {
-                currentDragType = DragType.Transform;
-            }
-            else
-            {
-                currentDragType = DragType.None;
-            }
-
-            if (currentDragType != dragTypeOld)
-            {
-                bool visible = currentDragType == DragType.Transform;
-                this.bgDragPoint.SetDragProp(visible, visible, visible);
-            }
-
-            dragTypeOld = currentDragType;
-
-            PropManager.Update();
-            LightManager.Update();
             EffectManager.Update();
         }
 
@@ -216,7 +200,12 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         private void OnCubeSmall(object sender, EventArgs args)
         {
-            this.bgDragPoint.DragPointScale = CubeSmall ? 0.4f : 1f;
+            this.bgDragPoint.DragPointScale = CubeSmall ? DragPointGeneral.smallCube : 1f;
+        }
+
+        private void OnCubeActive(object sender, EventArgs args)
+        {
+            this.bgDragPoint.gameObject.SetActive(CubeActive);
         }
     }
 

+ 39 - 106
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/LightManager.cs

@@ -2,44 +2,36 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using UnityEngine;
-using UnityEngine.Rendering;
 
 namespace COM3D2.MeidoPhotoStudio.Plugin
 {
-    using static MPSLight;
     internal class LightManager
     {
-        private List<MPSLight> LightList { get; set; } = new List<MPSLight>();
+        private List<DragPointLight> lightList = new List<DragPointLight>();
         private int selectedLightIndex = 0;
         public int SelectedLightIndex
         {
             get => selectedLightIndex;
             set
             {
-                selectedLightIndex = Mathf.Clamp(value, 0, LightList.Count - 1);
-                LightList[SelectedLightIndex].isActiveLight = true;
+                selectedLightIndex = Mathf.Clamp(value, 0, lightList.Count - 1);
+                lightList[SelectedLightIndex].IsActiveLight = true;
             }
         }
-        public string[] LightNameList => LightList.Select(light => LightName(light.Name)).ToArray();
-        public string ActiveLightName => LightName(LightList[SelectedLightIndex].Name);
-        public MPSLight CurrentLight
+        public string[] LightNameList => lightList.Select(light => LightName(light.Name)).ToArray();
+        public string ActiveLightName => LightName(lightList[SelectedLightIndex].Name);
+        public DragPointLight CurrentLight
         {
             get
             {
-                return LightList[SelectedLightIndex];
+                return lightList[SelectedLightIndex];
             }
         }
         public event EventHandler Rotate;
         public event EventHandler Scale;
         public event EventHandler ListModified;
         public event EventHandler Select;
-        private DragType dragTypeOld = DragType.None;
-        private DragType currentDragType = DragType.None;
-        private bool gizmoActive = false;
-        enum DragType
-        {
-            None, Move, Rotate, Scale, Delete, Select
-        }
+        // TODO: enabling and disabling gizmos for a variety of dragpoints
 
         public void Activate()
         {
@@ -49,98 +41,39 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         public void Deactivate()
         {
-            for (int i = 0; i < LightList.Count; i++)
+            for (int i = 0; i < lightList.Count; i++)
             {
-                DestroyLight(LightList[i]);
+                DestroyLight(lightList[i]);
             }
             selectedLightIndex = 0;
-            LightList.Clear();
+            lightList.Clear();
 
             GameMain.Instance.MainLight.Reset();
 
             Light mainLight = GameMain.Instance.MainLight.GetComponent<Light>();
             mainLight.type = LightType.Directional;
-            MPSLight.SetLightProperties(mainLight, new LightProperty());
-        }
-
-        public void Update()
-        {
-            if (Input.GetKey(KeyCode.Z))
-            {
-                currentDragType = DragType.Move;
-            }
-            else if (Input.GetKey(KeyCode.X))
-            {
-                currentDragType = DragType.Rotate;
-            }
-            else if (Input.GetKey(KeyCode.C))
-            {
-                currentDragType = DragType.Scale;
-            }
-            else if (Input.GetKey(KeyCode.D))
-            {
-                currentDragType = DragType.Delete;
-            }
-            else if (Input.GetKey(KeyCode.A))
-            {
-                currentDragType = DragType.Select;
-            }
-            else
-            {
-                currentDragType = DragType.None;
-            }
-
-            if (currentDragType != dragTypeOld) UpdateDragType();
-
-            dragTypeOld = currentDragType;
-        }
-
-        private void UpdateDragType()
-        {
-            foreach (MPSLight light in LightList)
-            {
-                bool active;
-                if (currentDragType >= DragType.Delete || currentDragType == DragType.None)
-                {
-                    if (currentDragType == DragType.Delete)
-                    {
-                        active = !light.IsMain;
-                    }
-                    else
-                    {
-                        active = currentDragType == DragType.Select;
-                    }
-                }
-                else
-                {
-                    if (light.SelectedLightType == MPSLightType.Normal)
-                    {
-                        active = false;
-                    }
-                    else if (light.SelectedLightType == MPSLightType.Point)
-                    {
-                        active = currentDragType != DragType.Rotate;
-                    }
-                    else
-                    {
-                        active = true;
-                    }
-                }
-                light.DragLight.SetDragProp(gizmoActive && active, active, active);
-            }
+            DragPointLight.SetLightProperties(mainLight, new LightProperty());
         }
 
         public void AddLight(GameObject lightGo = null, bool isMain = false)
         {
-            MPSLight light = new MPSLight(lightGo, isMain);
+            GameObject go = lightGo ?? new GameObject();
+            DragPointLight light = DragPoint.Make<DragPointLight>(
+                PrimitiveType.Cube, Vector3.one * 0.12f, DragPoint.LightBlue
+            );
+            light.Initialize(() => go.transform.position, () => go.transform.eulerAngles);
+            light.Set(go.transform);
+            light.IsMain = isMain;
+
             light.Rotate += OnRotate;
             light.Scale += OnScale;
             light.Delete += OnDelete;
             light.Select += OnSelect;
-            LightList.Add(light);
 
-            LightList[SelectedLightIndex].isActiveLight = false;
-            SelectedLightIndex = LightList.Count;
+            lightList.Add(light);
+
+            CurrentLight.IsActiveLight = false;
+            SelectedLightIndex = lightList.Count;
             OnListModified();
         }
 
@@ -155,8 +88,8 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         {
             if (lightIndex == 0) return;
 
-            DestroyLight(LightList[lightIndex]);
-            LightList.RemoveAt(lightIndex);
+            DestroyLight(lightList[lightIndex]);
+            lightList.RemoveAt(lightIndex);
 
             if (lightIndex <= SelectedLightIndex) SelectedLightIndex -= 1;
 
@@ -166,25 +99,25 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         public void SetColourModeActive(bool isColourMode)
         {
-            LightList[0].IsColourMode = isColourMode;
+            lightList[0].IsColourMode = isColourMode;
         }
 
         public void ClearLights()
         {
-            for (int i = LightList.Count - 1; i > 0; i--)
+            for (int i = lightList.Count - 1; i > 0; i--)
             {
                 DeleteLight(i);
             }
             selectedLightIndex = 0;
         }
 
-        private void DestroyLight(MPSLight light)
+        private void DestroyLight(DragPointLight light)
         {
             light.Rotate -= OnRotate;
             light.Scale -= OnScale;
             light.Delete -= OnDelete;
             light.Select -= OnSelect;
-            light.Destroy();
+            GameObject.Destroy(light.gameObject);
         }
 
         private string LightName(string name)
@@ -194,10 +127,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         private void OnDelete(object sender, EventArgs args)
         {
-            MPSLight theLight = (MPSLight)sender;
-            for (int i = 1; i < LightList.Count; i++)
+            DragPointLight theLight = (DragPointLight)sender;
+            for (int i = 1; i < lightList.Count; i++)
             {
-                MPSLight light = LightList[i];
+                DragPointLight light = lightList[i];
                 if (light == theLight)
                 {
                     DeleteLight(i);
@@ -208,17 +141,17 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         private void OnRotate(object sender, EventArgs args)
         {
-            OnTransformEvent((MPSLight)sender, Rotate);
+            OnTransformEvent((DragPointLight)sender, Rotate);
         }
 
         private void OnScale(object sender, EventArgs args)
         {
-            OnTransformEvent((MPSLight)sender, Scale);
+            OnTransformEvent((DragPointLight)sender, Scale);
         }
 
-        private void OnTransformEvent(MPSLight light, EventHandler handler)
+        private void OnTransformEvent(DragPointLight light, EventHandler handler)
         {
-            if (light.isActiveLight)
+            if (light.IsActiveLight)
             {
                 handler?.Invoke(this, EventArgs.Empty);
             }
@@ -226,8 +159,8 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         private void OnSelect(object sender, EventArgs args)
         {
-            MPSLight theLight = (MPSLight)sender;
-            int select = LightList.FindIndex(light => light == theLight);
+            DragPointLight theLight = (DragPointLight)sender;
+            int select = lightList.FindIndex(light => light == theLight);
             if (select >= 0)
             {
                 this.SelectedLightIndex = select;

+ 1 - 1
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/MeidoManager.cs

@@ -193,7 +193,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         }
         public int SelectedMeido { get; }
         public bool IsBody { get; }
-        public bool FromMeido { get; } = false;
+        public bool FromMeido { get; }
         public MeidoUpdateEventArgs(int meidoIndex, bool fromMaid = false, bool isBody = true)
         {
             this.SelectedMeido = meidoIndex;

+ 25 - 61
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/PropManager.cs

@@ -38,14 +38,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         }
         private static event EventHandler CubeActiveChange;
         private static event EventHandler CubeSmallChange;
-        private List<DragDogu> doguList = new List<DragDogu>();
-        private DragType dragTypeOld = DragType.None;
-        private DragType currentDragType = DragType.None;
-        private bool showGizmos = false;
-        private enum DragType
-        {
-            None, Move, Rotate, Scale, Delete, Other
-        }
+        private List<DragPointDogu> doguList = new List<DragPointDogu>();
         public int DoguCount => doguList.Count;
         public event EventHandler DoguListChange;
         public string[] PropNameList
@@ -72,7 +65,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         public void Deactivate()
         {
-            foreach (DragDogu dogu in doguList)
+            foreach (DragPointDogu dogu in doguList)
             {
                 dogu.Delete -= DeleteDogu;
                 GameObject.Destroy(dogu.gameObject);
@@ -81,40 +74,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             CubeSmallChange -= OnCubeSmall;
         }
 
-        public void Update()
-        {
-            if (Input.GetKeyDown(KeyCode.Space))
-            {
-                //     showGizmos = !showGizmos;
-                //     currentDragType = dragTypeOld = DragType.None;
-                //     UpdateDragType();
-            }
-
-            if (CubeActive && (Input.GetKey(KeyCode.Z) || Input.GetKey(KeyCode.X) || Input.GetKey(KeyCode.C)
-                || Input.GetKey(KeyCode.D))
-            )
-            {
-                currentDragType = DragType.Other;
-            }
-            else
-            {
-                currentDragType = DragType.None;
-            }
-
-            if (currentDragType != dragTypeOld) UpdateDragType();
-
-            dragTypeOld = currentDragType;
-        }
-
-        private void UpdateDragType()
-        {
-            bool dragPointActive = (currentDragType == DragType.Other);
-            foreach (DragDogu dogu in doguList)
-            {
-                dogu.SetDragProp(showGizmos, dragPointActive, dragPointActive);
-            }
-        }
-
         private GameObject GetDeploymentObject()
         {
             GameObject go = GameObject.Find("Deployment Object Parent");
@@ -276,13 +235,17 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
                 finalDogu.transform.position = doguPosition;
 
-                DragDogu dragDogu = BaseDrag.MakeDragPoint<DragDogu>(
-                    PrimitiveType.Cube, Vector3.one * 0.12f, BaseDrag.LightBlue
-                ).Initialize(finalDogu);
+                DragPointDogu dragDogu = DragPoint.Make<DragPointDogu>(
+                    PrimitiveType.Cube, Vector3.one * 0.12f, DragPoint.LightBlue
+                );
+                dragDogu.Initialize(() => finalDogu.transform.position, () => Vector3.zero);
+                dragDogu.Set(finalDogu.transform);
+                dragDogu.AddGizmo();
+                dragDogu.ConstantScale = true;
                 dragDogu.Delete += DeleteDogu;
-                dragDogu.SetDragProp(showGizmos, false, false);
+                dragDogu.DragPointScale = CubeSmall ? DragPointGeneral.smallCube : 1f;
+
                 doguList.Add(dragDogu);
-                dragDogu.DragPointScale = CubeSmall ? 0.4f : 1f;
                 OnDoguListChange();
             }
             else
@@ -291,14 +254,14 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
         }
 
-        public DragDogu GetDogu(int doguIndex)
+        public DragPointDogu GetDogu(int doguIndex)
         {
             if (doguList.Count == 0 || doguIndex >= doguList.Count || doguIndex < 0) return null;
             return doguList[doguIndex];
         }
 
         public void AttachProp(
-            int doguIndex, DragPointManager.AttachPoint attachPoint, Meido meido, bool worldPositionStays = true
+            int doguIndex, AttachPoint attachPoint, Meido meido, bool worldPositionStays = true
         )
         {
             if (doguList.Count == 0 || doguIndex >= doguList.Count || doguIndex < 0) return;
@@ -306,15 +269,15 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         }
 
         private void AttachProp(
-            DragDogu dragDogu, DragPointManager.AttachPoint attachPoint, Meido meido, bool worldPositionStays = true
+            DragPointDogu dragDogu, AttachPoint attachPoint, Meido meido, bool worldPositionStays = true
         )
         {
-            GameObject dogu = dragDogu.Dogu;
+            GameObject dogu = dragDogu.MyGameObject;
 
             Transform attachPointTransform = meido?.GetBoneTransform(attachPoint) ?? GetDeploymentObject().transform;
 
-            dragDogu.attachPointInfo = new DragPointManager.AttachPointInfo(
-                attachPoint: meido == null ? DragPointManager.AttachPoint.None : attachPoint,
+            dragDogu.attachPointInfo = new AttachPointInfo(
+                attachPoint: meido == null ? AttachPoint.None : attachPoint,
                 maidGuid: meido == null ? String.Empty : meido.Maid.status.guid,
                 maidIndex: meido == null ? -1 : meido.ActiveSlot
             );
@@ -342,18 +305,18 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         private void DetachProps(object sender, EventArgs args)
         {
-            foreach (DragDogu dogu in doguList)
+            foreach (DragPointDogu dogu in doguList)
             {
-                if (dogu.attachPointInfo.AttachPoint != DragPointManager.AttachPoint.None)
+                if (dogu.attachPointInfo.AttachPoint != AttachPoint.None)
                 {
-                    dogu.Dogu.transform.SetParent(GetDeploymentObject().transform, true);
+                    dogu.MyObject.SetParent(GetDeploymentObject().transform, true);
                 }
             }
         }
 
         private void ReattachProps(object sender, EventArgs args)
         {
-            foreach (DragDogu dragDogu in doguList)
+            foreach (DragPointDogu dragDogu in doguList)
             {
                 Meido meido = this.meidoManager.GetMeido(dragDogu.attachPointInfo.MaidGuid);
                 bool worldPositionStays = meido == null;
@@ -363,9 +326,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         private void DeleteDogu(object sender, EventArgs args)
         {
+            DragPointDogu dogu = (DragPointDogu)sender;
             doguList.RemoveAll(dragDogu =>
                 {
-                    if (dragDogu.DeleteMe)
+                    if (dragDogu == dogu)
                     {
                         GameObject.Destroy(dragDogu.gameObject);
                         return true;
@@ -378,9 +342,9 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         private void OnCubeSmall(object sender, EventArgs args)
         {
-            foreach (DragDogu dogu in doguList)
+            foreach (DragPointDogu dogu in doguList)
             {
-                dogu.DragPointScale = CubeSmall ? 0.4f : 1f;
+                dogu.DragPointScale = CubeSmall ? DragPointGeneral.smallCube : 1f;
             }
         }
 

+ 0 - 270
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/BaseDrag.cs

@@ -1,270 +0,0 @@
-using System;
-using UnityEngine;
-
-namespace COM3D2.MeidoPhotoStudio.Plugin
-{
-    using static CustomGizmo;
-    // TODO: Finalize dragpopint scaling
-    internal abstract class BaseDrag : MonoBehaviour
-    {
-        private const float doubleClickSensitivity = 0.3f;
-        protected const int upperArm = 0;
-        protected const int foreArm = 1;
-        protected const int hand = 2;
-        protected const int upperArmRot = 0;
-        protected const int handRot = 1;
-        private GameObject gizmoGo;
-        protected Maid maid;
-        protected Meido meido;
-        protected Func<Vector3> position;
-        protected Func<Vector3> rotation;
-        protected Renderer dragPointRenderer;
-        protected Collider dragPointCollider;
-        protected Vector3 worldPoint;
-        protected Vector3 mousePos;
-        private DragType dragType = DragType.None;
-        protected DragType CurrentDragType
-        {
-            get => dragType;
-            set
-            {
-                dragType = value;
-                reInitDrag = dragType != dragTypeOld;
-                dragTypeOld = dragType;
-            }
-        }
-        protected DragType dragTypeOld;
-        protected float doubleClickStart = 0f;
-        protected bool reInitDrag = false;
-        protected bool isPlaying;
-        protected CustomGizmo gizmo;
-        protected GizmoType CurrentGizmoType
-        {
-            get => gizmo?.CurrentGizmoType ?? GizmoType.None;
-            set
-            {
-                if (gizmo != null)
-                {
-                    if (GizmoActive) gizmo.CurrentGizmoType = value;
-                }
-            }
-        }
-        public Vector3 InitialScale { get; private set; }
-        private float dragPointScale = 1f;
-        public float DragPointScale
-        {
-            get => dragPointScale;
-            set
-            {
-                dragPointScale = value;
-                transform.localScale = InitialScale * dragPointScale;
-            }
-        }
-        public bool IsBone { get; set; }
-        public bool GizmoVisible
-        {
-            get => gizmo?.Visible ?? false;
-            set
-            {
-                if (gizmo != null) gizmo.Visible = value;
-            }
-        }
-        private bool gizmoActive = false;
-        public bool GizmoActive
-        {
-            get => gizmoActive;
-            set
-            {
-                if (gizmoGo != null)
-                {
-                    gizmoActive = value;
-                    gizmoGo.SetActive(gizmoActive);
-                    GizmoVisible = gizmoActive;
-                }
-            }
-        }
-        private bool dragPointVisible;
-        public bool DragPointVisible
-        {
-            get => dragPointVisible;
-            set
-            {
-                dragPointVisible = value;
-                dragPointRenderer.enabled = dragPointVisible;
-            }
-        }
-        private bool dragPointActive;
-        public bool DragPointActive
-        {
-            get => dragPointActive;
-            set
-            {
-                dragPointActive = value;
-                dragPointCollider.enabled = dragPointActive;
-            }
-        }
-        public GizmoMode CurrentGizmoMode
-        {
-            get => gizmo?.gizmoMode ?? GizmoMode.Local;
-            set
-            {
-                if (gizmo != null)
-                {
-                    if (GizmoActive) gizmo.gizmoMode = value;
-                }
-            }
-        }
-        public event EventHandler DragEvent;
-        protected enum DragType
-        {
-            None, Select, Delete,
-            MoveXZ, MoveY, RotLocalXZ, RotY, RotLocalY,
-            Scale
-        }
-
-        public static Material LightBlue = new Material(Shader.Find("Transparent/Diffuse"))
-        {
-            color = new Color(0.4f, 0.4f, 1f, 0.3f)
-        };
-
-        public static Material Blue = new Material(Shader.Find("Transparent/Diffuse"))
-        {
-            color = new Color(0.5f, 0.5f, 1f, 0.8f)
-        };
-
-        public static GameObject MakeDragPoint(PrimitiveType primitiveType, Vector3 scale, Material material)
-        {
-            GameObject dragPoint = GameObject.CreatePrimitive(primitiveType);
-            dragPoint.transform.localScale = scale;
-            dragPoint.GetComponent<Renderer>().material = material;
-            dragPoint.layer = 8;
-            return dragPoint;
-        }
-
-        public static T MakeDragPoint<T>(
-            PrimitiveType primitiveType, Vector3 scale, Material material
-        ) where T : BaseDrag
-        {
-            GameObject dragPoint = MakeDragPoint(primitiveType, scale, material);
-            return dragPoint.AddComponent<T>();
-        }
-
-        public BaseDrag Initialize(Meido meido, Func<Vector3> position, Func<Vector3> rotation)
-        {
-            this.InitializeDragPoint(position, rotation);
-            this.meido = meido;
-            this.maid = meido.Maid;
-            isPlaying = !meido.IsStop;
-            return this;
-        }
-
-        protected void InitializeDragPoint(Func<Vector3> position, Func<Vector3> rotation)
-        {
-            this.InitialScale = transform.localScale;
-            this.position = position;
-            this.rotation = rotation;
-            this.dragPointRenderer = GetComponent<Renderer>();
-            this.dragPointCollider = GetComponent<Collider>();
-            this.DragPointVisible = true;
-        }
-
-        protected void InitializeGizmo(Transform target, float scale = 0.25f, GizmoMode mode = GizmoMode.Local)
-        {
-            gizmoGo = CustomGizmo.MakeGizmo(target, scale, mode);
-            gizmo = gizmoGo.GetComponent<CustomGizmo>();
-            if (meido != null)
-            {
-                gizmo.GizmoDrag += (s, a) =>
-                {
-                    meido.IsStop = true;
-                    isPlaying = false;
-                };
-            }
-
-            GizmoActive = false;
-            GizmoVisible = false;
-        }
-
-        public void SetDragProp(bool gizmoActive, bool dragPointActive, bool dragPointVisible)
-        {
-            this.GizmoActive = gizmoActive;
-            this.DragPointActive = dragPointActive;
-            this.DragPointVisible = dragPointVisible;
-        }
-
-        public void SetDragProp(bool gizmoActive, bool dragPointActive, bool dragPointVisible, GizmoMode mode)
-        {
-            SetDragProp(gizmoActive, dragPointActive, dragPointVisible);
-            this.CurrentGizmoMode = mode;
-        }
-
-        protected virtual void InitializeDrag()
-        {
-            worldPoint = Camera.main.WorldToScreenPoint(transform.position);
-            mousePos = Input.mousePosition;
-
-            isPlaying = !meido?.IsStop ?? false;
-        }
-
-        protected virtual void DoubleClick() { }
-        protected abstract void Drag();
-        protected abstract void GetDragType();
-        protected virtual void OnMouseUp()
-        {
-            if ((Time.time - doubleClickStart) < doubleClickSensitivity)
-            {
-                doubleClickStart = -1;
-                DoubleClick();
-            }
-            else
-            {
-                doubleClickStart = Time.time;
-            }
-        }
-
-        protected virtual void Update()
-        {
-            GetDragType();
-
-            transform.position = position();
-            transform.eulerAngles = rotation();
-        }
-
-        protected virtual void OnMouseDown()
-        {
-            InitializeDrag();
-        }
-
-        protected virtual void OnMouseDrag()
-        {
-            if (CurrentDragType == DragType.Select) return;
-
-            if (reInitDrag)
-            {
-                reInitDrag = false;
-                InitializeDrag();
-            }
-
-            if (mousePos != Input.mousePosition) Drag();
-        }
-
-        private void OnEnable()
-        {
-            if (position != null)
-            {
-                transform.position = position();
-                transform.eulerAngles = rotation();
-            }
-        }
-
-        private void OnDestroy()
-        {
-            GameObject.Destroy(gizmo);
-        }
-
-        protected void OnDragEvent()
-        {
-            DragEvent?.Invoke(null, EventArgs.Empty);
-        }
-    }
-}

+ 0 - 162
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragBody.cs

@@ -1,162 +0,0 @@
-using System;
-using UnityEngine;
-
-namespace COM3D2.MeidoPhotoStudio.Plugin
-{
-    using static CustomGizmo;
-    internal class DragBody : BaseDrag
-    {
-        private Vector3 off;
-        private Vector3 off2;
-        private Vector3 mousePos2;
-        private float maidScale;
-        private Vector3 maidRot;
-        private bool scaling;
-        public event EventHandler Select;
-        public event EventHandler Scale;
-
-        protected override void GetDragType()
-        {
-            bool holdShift = Utility.GetModKey(Utility.ModKey.Shift);
-            if (Input.GetKey(KeyCode.A))
-            {
-                CurrentDragType = DragType.Select;
-            }
-            else if (Input.GetKey(KeyCode.Z))
-            {
-                if (Utility.GetModKey(Utility.ModKey.Control)) CurrentDragType = DragType.MoveY;
-                else CurrentDragType = holdShift ? DragType.RotY : DragType.MoveXZ;
-            }
-            else if (Input.GetKey(KeyCode.X))
-            {
-                CurrentDragType = holdShift ? DragType.RotLocalY : DragType.RotLocalXZ;
-            }
-            else if (Input.GetKey(KeyCode.C))
-            {
-                CurrentDragType = DragType.Scale;
-            }
-            else
-            {
-                CurrentDragType = DragType.None;
-            }
-        }
-
-        protected override void InitializeDrag()
-        {
-            if (CurrentDragType == DragType.Select)
-            {
-                Select?.Invoke(this, EventArgs.Empty);
-                return;
-            }
-
-            base.InitializeDrag();
-
-            maidScale = maid.transform.localScale.x;
-            maidRot = maid.transform.localEulerAngles;
-            off = transform.position - Camera.main.ScreenToWorldPoint(
-                new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z)
-            );
-            off2 = new Vector3(
-                transform.position.x - maid.transform.position.x,
-                transform.position.y - maid.transform.position.y,
-                transform.position.z - maid.transform.position.z
-            );
-        }
-
-        protected override void DoubleClick()
-        {
-            if (CurrentDragType == DragType.Scale)
-            {
-                maid.transform.localScale = new Vector3(1f, 1f, 1f);
-                Scale?.Invoke(this, EventArgs.Empty);
-            }
-
-            if (CurrentDragType == DragType.RotLocalY || CurrentDragType == DragType.RotLocalXZ)
-                maid.transform.eulerAngles = new Vector3(0f, maid.transform.eulerAngles.y, 0f);
-        }
-
-        protected override void OnMouseUp()
-        {
-            base.OnMouseUp();
-            if (scaling)
-            {
-                scaling = false;
-                Scale?.Invoke(this, EventArgs.Empty);
-            }
-        }
-
-        protected override void Drag()
-        {
-            Vector3 pos = Camera.main.ScreenToWorldPoint(
-                new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z)
-            ) + off - off2;
-
-            if (CurrentDragType == DragType.MoveXZ)
-            {
-                maid.transform.position = new Vector3(pos.x, maid.transform.position.y, pos.z);
-            }
-
-            if (CurrentDragType == DragType.MoveY)
-            {
-                maid.transform.position = new Vector3(maid.transform.position.x, pos.y, maid.transform.position.z);
-            }
-
-            if (CurrentDragType == DragType.RotY)
-            {
-                Vector3 posOther = Input.mousePosition - mousePos;
-                maid.transform.eulerAngles = new Vector3(
-                    maid.transform.eulerAngles.x, maidRot.y - posOther.x / 3f, maid.transform.eulerAngles.z
-                );
-
-            }
-
-            if (CurrentDragType == DragType.RotLocalXZ)
-            {
-                Vector3 posOther = Input.mousePosition - mousePos;
-                Transform transform = Camera.main.transform;
-                Vector3 vector3_3 = transform.TransformDirection(Vector3.right);
-                Vector3 vector3_4 = transform.TransformDirection(Vector3.forward);
-                transform.TransformDirection(Vector3.forward);
-                if (mousePos2 != Input.mousePosition)
-                {
-                    maid.transform.localEulerAngles = maidRot;
-                    maid.transform.RotateAround(
-                        maid.transform.position,
-                        new Vector3(vector3_3.x, 0.0f, vector3_3.z),
-                        posOther.y / 4f
-                    );
-                    maid.transform.RotateAround(
-                        maid.transform.position,
-                        new Vector3(vector3_4.x, 0.0f, vector3_4.z),
-                        -posOther.x / 6.0f
-                    );
-                }
-                mousePos2 = Input.mousePosition;
-            }
-
-            if (CurrentDragType == DragType.RotLocalY)
-            {
-                Vector3 posOther = Input.mousePosition - mousePos;
-                Transform transform = Camera.main.transform;
-                transform.TransformDirection(Vector3.forward);
-                if (mousePos2 != Input.mousePosition)
-                {
-                    maid.transform.localEulerAngles = maidRot;
-                    maid.body0.transform.localRotation = Quaternion.Euler(maid.transform.localEulerAngles)
-                        * Quaternion.AngleAxis((-posOther.x / 2.2f), Vector3.up);
-                }
-
-                mousePos2 = Input.mousePosition;
-            }
-
-            if (CurrentDragType == DragType.Scale)
-            {
-                scaling = true;
-                Vector3 posOther = Input.mousePosition - mousePos;
-                float scale = maidScale + posOther.y / 200f;
-                if (scale < 0.1f) scale = 0.1f;
-                maid.transform.localScale = new Vector3(scale, scale, scale);
-            }
-        }
-    }
-}

+ 0 - 132
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragHead.cs

@@ -1,132 +0,0 @@
-using System;
-using UnityEngine;
-
-namespace COM3D2.MeidoPhotoStudio.Plugin
-{
-    internal class DragHead : BaseDrag
-    {
-        private Transform head;
-        private Vector3 rotate;
-        private Vector3 eyeRotL;
-        private Vector3 eyeRotR;
-        private Vector3 defEyeRotL;
-        private Vector3 defEyeRotR;
-        private Vector3 mousePosOther;
-        public event EventHandler Select;
-        public bool IsIK { get; set; }
-
-        public DragHead Initialize(Transform head, Meido meido, Func<Vector3> posFunc, Func<Vector3> rotFunc)
-        {
-            base.Initialize(meido, posFunc, rotFunc);
-            this.head = head;
-
-            // default eye rotations
-            defEyeRotL = this.maid.body0.quaDefEyeL.eulerAngles;
-            defEyeRotR = this.maid.body0.quaDefEyeR.eulerAngles;
-
-            InitializeGizmo(this.head);
-            return this;
-        }
-
-        protected override void GetDragType()
-        {
-            bool shift = Utility.GetModKey(Utility.ModKey.Shift);
-            if (Utility.GetModKey(Utility.ModKey.Alt) && Utility.GetModKey(Utility.ModKey.Control))
-            {
-                // eyes
-                CurrentDragType = Utility.GetModKey(Utility.ModKey.Shift) ? DragType.MoveY : DragType.MoveXZ;
-            }
-            else if (Utility.GetModKey(Utility.ModKey.Alt))
-            {
-                // head
-                CurrentDragType = shift ? DragType.RotLocalY : DragType.RotLocalXZ;
-            }
-            else if (Input.GetKey(KeyCode.A))
-            {
-                CurrentDragType = DragType.Select;
-            }
-            else
-            {
-                CurrentDragType = DragType.None;
-            }
-        }
-
-        protected override void DoubleClick()
-        {
-            if (CurrentDragType == DragType.MoveXZ || CurrentDragType == DragType.MoveY)
-            {
-                maid.body0.quaDefEyeL.eulerAngles = defEyeRotL;
-                maid.body0.quaDefEyeR.eulerAngles = defEyeRotR;
-            }
-            if (CurrentDragType == DragType.RotLocalY || CurrentDragType == DragType.RotLocalXZ)
-            {
-                meido.IsFreeLook = !meido.IsFreeLook;
-            }
-        }
-
-        protected override void InitializeDrag()
-        {
-            if (CurrentDragType == DragType.Select)
-            {
-                Select?.Invoke(this, EventArgs.Empty);
-                return;
-            }
-
-            if (IsBone) return;
-
-            base.InitializeDrag();
-
-            rotate = head.localEulerAngles;
-
-            eyeRotL = maid.body0.quaDefEyeL.eulerAngles;
-            eyeRotR = maid.body0.quaDefEyeR.eulerAngles;
-            mousePosOther = Input.mousePosition - mousePos;
-        }
-
-        protected override void Drag()
-        {
-            if (!IsIK || (CurrentDragType == DragType.None || CurrentDragType == DragType.Select) || IsBone) return;
-
-            if (!(CurrentDragType == DragType.MoveXZ || CurrentDragType == DragType.MoveY))
-            {
-                if (isPlaying) meido.IsStop = true;
-            }
-
-            Vector3 pos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z);
-            Vector3 vec31 = Input.mousePosition - mousePos;
-            Transform t = GameMain.Instance.MainCamera.gameObject.transform;
-            Vector3 vec32 = t.TransformDirection(Vector3.right);
-            Vector3 vec33 = t.TransformDirection(Vector3.forward);
-
-            if (CurrentDragType == DragType.RotLocalXZ)
-            {
-                head.localEulerAngles = rotate;
-                head.RotateAround(head.position, new Vector3(vec32.x, 0.0f, vec32.z), vec31.y / 3f);
-                head.RotateAround(head.position, new Vector3(vec33.x, 0.0f, vec33.z), (-vec31.x / 4.5f));
-            }
-
-            if (CurrentDragType == DragType.RotLocalY)
-            {
-                head.localEulerAngles = rotate;
-                head.localRotation = Quaternion.Euler(head.localEulerAngles)
-                    * Quaternion.AngleAxis(vec31.x / 3f, Vector3.right);
-            }
-
-            if (CurrentDragType == DragType.MoveXZ || CurrentDragType == DragType.MoveY)
-            {
-                int inv = CurrentDragType == DragType.MoveY ? -1 : 1;
-                Vector3 vec34 = new Vector3(eyeRotR.x, eyeRotR.y + vec31.x / 10f, eyeRotR.z + vec31.y / 10f);
-
-                mousePosOther.y = vec31.y;
-                mousePosOther.x = vec31.x;
-
-                maid.body0.quaDefEyeL.eulerAngles = new Vector3(
-                    eyeRotL.x, eyeRotL.y - mousePosOther.x / 10f, eyeRotL.z - mousePosOther.y / 10f
-                );
-                maid.body0.quaDefEyeR.eulerAngles = new Vector3(
-                    eyeRotR.x, eyeRotR.y + inv * mousePosOther.x / 10f, eyeRotR.z + mousePosOther.y / 10f
-                );
-            }
-        }
-    }
-}

+ 0 - 116
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragJointFinger.cs

@@ -1,116 +0,0 @@
-using System;
-using UnityEngine;
-
-namespace COM3D2.MeidoPhotoStudio.Plugin
-{
-    internal class DragJointFinger : BaseDrag
-    {
-        private readonly TBody.IKCMO IK = new TBody.IKCMO();
-        private readonly GameObject[] otherIK = new GameObject[3];
-        private Transform[] ikChain;
-        private Vector3[] jointRotation = new Vector3[2];
-        private Vector3 off;
-        private Vector3 off2;
-        private bool baseFinger;
-
-        public DragJointFinger Initialize(
-            Transform[] ikChain, bool baseFinger,
-            Meido meido, Func<Vector3> position, Func<Vector3> rotation)
-        {
-            base.Initialize(meido, position, rotation);
-            this.ikChain = ikChain;
-            this.baseFinger = baseFinger;
-            InitializeIK();
-            InitializeIK2();
-            return this;
-        }
-        public void InitializeIK()
-        {
-            IK.Init(ikChain[upperArm], ikChain[foreArm], ikChain[hand], maid.body0);
-        }
-
-        private void InitializeIK2()
-        {
-            for (int i = 0; i < otherIK.Length; i++)
-            {
-                otherIK[i] = new GameObject();
-                otherIK[i].transform.position = this.ikChain[i].position;
-                otherIK[i].transform.localRotation = this.ikChain[i].localRotation;
-            }
-        }
-
-        protected override void GetDragType()
-        {
-            if (Utility.GetModKey(Utility.ModKey.Shift))
-            {
-                CurrentDragType = DragType.RotLocalY;
-            }
-            else
-            {
-                CurrentDragType = DragType.None;
-            }
-        }
-
-        protected override void InitializeDrag()
-        {
-            base.InitializeDrag();
-
-            IKCtrlData ikData = maid.body0.IKCtrl.GetIKData("左手");
-            off = transform.position - Camera.main.ScreenToWorldPoint(
-                new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z)
-            );
-            off2 = new Vector3(
-                transform.position.x - ikChain[hand].position.x,
-                transform.position.y - ikChain[hand].position.y,
-                transform.position.z - ikChain[hand].position.z
-            );
-
-            jointRotation[upperArmRot] = ikChain[upperArm].localEulerAngles;
-            jointRotation[handRot] = ikChain[hand].localEulerAngles;
-            InitializeIK();
-        }
-
-        protected override void Drag()
-        {
-            if (isPlaying) meido.IsStop = true;
-
-            IKCtrlData ikData = maid.body0.IKCtrl.GetIKData("左手");
-            Vector3 pos = Camera.main.ScreenToWorldPoint(
-                new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z)
-            ) + off - off2;
-
-            if (CurrentDragType == DragType.None)
-            {
-                IK.Porc(ikChain[upperArm], ikChain[foreArm], ikChain[hand], pos, Vector3.zero, ikData);
-
-                if (baseFinger)
-                {
-                    jointRotation[handRot] = ikChain[hand].localEulerAngles;
-                    jointRotation[upperArmRot] = ikChain[upperArm].localEulerAngles;
-                    ikChain[upperArm].localEulerAngles = jointRotation[upperArm];
-                    ikChain[hand].localEulerAngles = jointRotation[handRot];
-                }
-                else
-                {
-                    ikChain[hand].localEulerAngles = new Vector3(
-                        jointRotation[handRot].x, jointRotation[handRot].y, ikChain[hand].localEulerAngles.z
-                    );
-                    ikChain[upperArm].localEulerAngles = new Vector3(
-                        jointRotation[upperArmRot].x, jointRotation[upperArmRot].y, ikChain[upperArm].localEulerAngles.z
-                    );
-                }
-            }
-            else
-            {
-                if (CurrentDragType == DragType.RotLocalY)
-                {
-                    Vector3 vec31 = Input.mousePosition - mousePos;
-                    ikChain[upperArm].localEulerAngles = jointRotation[upperArmRot];
-                    ikChain[upperArm].localRotation = Quaternion.Euler(ikChain[upperArm].localEulerAngles)
-                        * Quaternion.AngleAxis((-vec31.x / 1.5f), Vector3.right);
-                }
-            }
-
-        }
-    }
-}

+ 0 - 102
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragJointForearm.cs

@@ -1,102 +0,0 @@
-using System;
-using UnityEngine;
-
-namespace COM3D2.MeidoPhotoStudio.Plugin
-{
-    internal class DragJointForearm : BaseDrag
-    {
-        private readonly TBody.IKCMO IK = new TBody.IKCMO();
-        private readonly GameObject[] otherIK = new GameObject[3];
-        private Transform[] ikChain;
-        private Vector3[] jointRotation = new Vector3[2];
-        private Vector3 off;
-        private Vector3 off2;
-        private bool knee = false;
-
-        public DragJointForearm Initialize(
-            Transform[] ikChain, bool knee,
-            Meido meido, Func<Vector3> position, Func<Vector3> rotation
-        )
-        {
-            base.Initialize(meido, position, rotation);
-            this.ikChain = ikChain;
-            this.knee = knee;
-
-            for (int i = 0; i < otherIK.Length; i++)
-            {
-                otherIK[i] = new GameObject();
-                otherIK[i].transform.position = this.ikChain[i].position;
-                otherIK[i].transform.localRotation = this.ikChain[i].localRotation;
-            }
-
-            InitializeIK();
-
-            InitializeGizmo(this.ikChain[hand]);
-            return this;
-        }
-
-        public void InitializeIK()
-        {
-            IK.Init(ikChain[upperArm], ikChain[foreArm], ikChain[hand], maid.body0);
-        }
-
-        protected override void GetDragType()
-        {
-            if (knee && Utility.GetModKey(Utility.ModKey.Shift) && Utility.GetModKey(Utility.ModKey.Alt))
-            {
-                CurrentDragType = DragType.RotLocalY;
-            }
-            else
-            {
-                CurrentDragType = DragType.None;
-            }
-        }
-
-        protected override void InitializeDrag()
-        {
-            base.InitializeDrag();
-
-            off = transform.position - Camera.main.ScreenToWorldPoint(
-                new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z)
-            );
-            off2 = new Vector3(
-                transform.position.x - ikChain[hand].position.x,
-                transform.position.y - ikChain[hand].position.y,
-                transform.position.z - ikChain[hand].position.z
-            );
-
-            jointRotation[upperArmRot] = ikChain[upperArm].localEulerAngles;
-            jointRotation[handRot] = ikChain[hand].localEulerAngles;
-            InitializeIK();
-        }
-
-        protected override void Drag()
-        {
-            if (isPlaying) meido.IsStop = true;
-
-            IKCtrlData ikData = maid.body0.IKCtrl.GetIKData("左手");
-            Vector3 pos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z)) + off - off2;
-
-            if (CurrentDragType == DragType.None)
-            {
-                IK.Porc(ikChain[upperArm], ikChain[foreArm], ikChain[hand], pos, Vector3.zero, ikData);
-
-                jointRotation[handRot] = ikChain[hand].localEulerAngles;
-                jointRotation[upperArmRot] = ikChain[upperArm].localEulerAngles;
-                ikChain[upperArm].localEulerAngles = jointRotation[upperArm];
-                ikChain[hand].localEulerAngles = jointRotation[handRot];
-            }
-            else
-            {
-                Vector3 vec31 = Input.mousePosition - mousePos;
-
-                if (CurrentDragType == DragType.RotLocalY)
-                {
-                    ikChain[upperArm].localEulerAngles = jointRotation[upperArmRot];
-                    ikChain[upperArm].localRotation = Quaternion.Euler(ikChain[upperArm].localEulerAngles)
-                        * Quaternion.AngleAxis((-vec31.x / 1.5f), Vector3.right);
-                }
-            }
-        }
-    }
-}

+ 0 - 133
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragJointHand.cs

@@ -1,133 +0,0 @@
-using System;
-using UnityEngine;
-
-namespace COM3D2.MeidoPhotoStudio.Plugin
-{
-    internal class DragJointHand : BaseDrag
-    {
-        private readonly TBody.IKCMO IK = new TBody.IKCMO();
-        private readonly GameObject[] otherIK = new GameObject[3];
-        private Transform[] ikChain;
-        private Transform[] ikChainLock;
-        private Vector3[] jointRotation = new Vector3[2];
-        private Vector3 off;
-        private Vector3 off2;
-        private int foot = 1;
-
-        public DragJointHand Initialize(
-            Transform[] ikChain, bool foot,
-            Meido meido, Func<Vector3> position, Func<Vector3> rotation
-        )
-        {
-            base.Initialize(meido, position, rotation);
-            this.ikChain = ikChain;
-            this.foot = foot ? -1 : 1;
-            this.ikChainLock = new Transform[3] {
-                ikChain[foreArm],
-                ikChain[foreArm],
-                ikChain[hand]
-            };
-
-            InitializeIK();
-            InitializeIK2();
-            InitializeGizmo(this.ikChain[hand]);
-            return this;
-        }
-        public void InitializeIK()
-        {
-            IK.Init(ikChain[upperArm], ikChain[foreArm], ikChain[hand], maid.body0);
-        }
-
-        private void InitializeIK2()
-        {
-            for (int i = 0; i < otherIK.Length; i++)
-            {
-                otherIK[i] = new GameObject();
-                otherIK[i].transform.position = this.ikChain[i].position;
-                otherIK[i].transform.localRotation = this.ikChain[i].localRotation;
-            }
-        }
-
-        protected override void GetDragType()
-        {
-            if (Utility.GetModKey(Utility.ModKey.Shift) && Utility.GetModKey(Utility.ModKey.Alt))
-            {
-                CurrentDragType = DragType.RotLocalY;
-            }
-            else if (Utility.GetModKey(Utility.ModKey.Alt))
-            {
-                CurrentDragType = DragType.RotLocalXZ;
-            }
-            else if (Utility.GetModKey(Utility.ModKey.Control))
-            {
-                CurrentDragType = DragType.MoveXZ;
-            }
-            else
-            {
-                CurrentDragType = DragType.None;
-            }
-        }
-
-        protected override void InitializeDrag()
-        {
-            base.InitializeDrag();
-
-            Transform[] ikChain = CurrentDragType == DragType.MoveXZ ? this.ikChainLock : this.ikChain;
-
-            IKCtrlData ikData = maid.body0.IKCtrl.GetIKData("左手");
-            off = transform.position - Camera.main.ScreenToWorldPoint(
-                new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z)
-            );
-            off2 = new Vector3(
-                transform.position.x - ikChain[hand].position.x,
-                transform.position.y - ikChain[hand].position.y,
-                transform.position.z - ikChain[hand].position.z);
-
-            jointRotation[upperArmRot] = ikChain[upperArm].localEulerAngles;
-            jointRotation[handRot] = ikChain[hand].localEulerAngles;
-            InitializeIK();
-        }
-
-        protected override void Drag()
-        {
-            if (isPlaying) meido.IsStop = true;
-
-            IKCtrlData ikData = maid.body0.IKCtrl.GetIKData("左手");
-            Vector3 pos = Camera.main.ScreenToWorldPoint(
-                new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z)
-            ) + off - off2;
-
-            if (CurrentDragType == DragType.None || CurrentDragType == DragType.MoveXZ)
-            {
-                Transform[] ikChain = CurrentDragType == DragType.MoveXZ ? this.ikChainLock : this.ikChain;
-
-                IK.Porc(ikChain[upperArm], ikChain[foreArm], ikChain[hand], pos, Vector3.zero, ikData);
-
-                jointRotation[handRot] = ikChain[hand].localEulerAngles;
-                jointRotation[upperArmRot] = ikChain[upperArm].localEulerAngles;
-                ikChain[upperArm].localEulerAngles = jointRotation[upperArm];
-                ikChain[hand].localEulerAngles = jointRotation[handRot];
-            }
-            else
-            {
-                Vector3 vec31 = Input.mousePosition - mousePos;
-
-                if (CurrentDragType == DragType.RotLocalY)
-                {
-                    ikChain[hand].localEulerAngles = jointRotation[handRot];
-                    ikChain[hand].localRotation = Quaternion.Euler(ikChain[hand].localEulerAngles)
-                        * Quaternion.AngleAxis(vec31.x / 1.5f, Vector3.right);
-                }
-
-                if (CurrentDragType == DragType.RotLocalXZ)
-                {
-                    ikChain[hand].localEulerAngles = jointRotation[handRot];
-                    ikChain[hand].localRotation = Quaternion.Euler(ikChain[hand].localEulerAngles)
-                        * Quaternion.AngleAxis(foot * vec31.x / 1.5f, Vector3.up);
-                    ikChain[hand].localRotation = Quaternion.Euler(ikChain[hand].localEulerAngles)
-                        * Quaternion.AngleAxis(foot * vec31.y / 1.5f, Vector3.forward);
-                }
-            }
-        }
-    }
-}

+ 0 - 91
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragMune.cs

@@ -1,91 +0,0 @@
-using System;
-using UnityEngine;
-
-namespace COM3D2.MeidoPhotoStudio.Plugin
-{
-    internal class DragMune : BaseDrag
-    {
-        private readonly TBody.IKCMO IK = new TBody.IKCMO();
-        private readonly GameObject[] things = new GameObject[3];
-        private Transform[] ikChain;
-        private Vector3[] jointRotation = new Vector3[2];
-        private Vector3 off;
-        private Vector3 off2;
-
-        public DragMune Initialize(Transform[] ikChain, Meido meido, Func<Vector3> position, Func<Vector3> rotation)
-        {
-            base.Initialize(meido, position, rotation);
-            this.ikChain = ikChain;
-
-            for (int i = 0; i < things.Length; i++)
-            {
-                things[i] = new GameObject();
-                things[i].transform.position = this.ikChain[i].position;
-                things[i].transform.localRotation = this.ikChain[i].localRotation;
-            }
-
-            InitializeIK();
-            return this;
-        }
-
-        public void InitializeIK()
-        {
-            IK.Init(ikChain[upperArm], ikChain[foreArm], ikChain[hand], maid.body0);
-        }
-
-        protected override void GetDragType()
-        {
-            if (Input.GetKey(KeyCode.LeftControl) && Input.GetKey(KeyCode.LeftAlt))
-            {
-                CurrentDragType = DragType.RotLocalXZ;
-            }
-            else
-            {
-                CurrentDragType = DragType.None;
-            }
-        }
-
-        protected override void DoubleClick()
-        {
-            if (CurrentDragType == DragType.RotLocalXZ) meido.SetMune();
-        }
-
-        protected override void InitializeDrag()
-        {
-            base.InitializeDrag();
-
-            off = transform.position - Camera.main.ScreenToWorldPoint(
-                new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z)
-            );
-            off2 = new Vector3(
-                transform.position.x - ikChain[hand].position.x,
-                transform.position.y - ikChain[hand].position.y,
-                transform.position.z - ikChain[hand].position.z);
-
-            jointRotation[upperArmRot] = ikChain[upperArm].localEulerAngles;
-            jointRotation[handRot] = ikChain[hand].localEulerAngles;
-            meido.SetMune(true);
-        }
-
-        protected override void Drag()
-        {
-            if (CurrentDragType == DragType.None) return;
-
-            if (isPlaying) meido.IsStop = true;
-            IKCtrlData ikData = maid.body0.IKCtrl.GetIKData("左手");
-            Vector3 pos = Camera.main.ScreenToWorldPoint(
-                new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z)
-            ) + off - off2;
-
-            if (CurrentDragType == DragType.RotLocalXZ)
-            {
-                IK.Porc(ikChain[upperArm], ikChain[foreArm], ikChain[hand], pos, Vector3.zero, ikData);
-
-                jointRotation[handRot] = ikChain[hand].localEulerAngles;
-                jointRotation[upperArmRot] = ikChain[upperArm].localEulerAngles;
-                ikChain[upperArm].localEulerAngles = jointRotation[upperArm];
-                ikChain[hand].localEulerAngles = jointRotation[handRot];
-            }
-        }
-    }
-}

+ 0 - 64
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragPelvis.cs

@@ -1,64 +0,0 @@
-using System;
-using UnityEngine;
-
-namespace COM3D2.MeidoPhotoStudio.Plugin
-{
-    internal class DragPelvis : BaseDrag
-    {
-        private Transform pelvis;
-        private Vector3 pelvisRotation;
-
-        public DragPelvis Initialize(Transform pelvis, Meido meido, Func<Vector3> position, Func<Vector3> rotation)
-        {
-            base.Initialize(meido, position, rotation);
-            this.pelvis = pelvis;
-            return this;
-        }
-
-        protected override void GetDragType()
-        {
-            bool shift = Input.GetKey(KeyCode.LeftShift);
-            if (Input.GetKey(KeyCode.LeftAlt))
-            {
-                CurrentDragType = shift ? DragType.RotLocalY : DragType.RotLocalXZ;
-            }
-            else
-            {
-                CurrentDragType = DragType.None;
-            }
-        }
-
-        protected override void InitializeDrag()
-        {
-            base.InitializeDrag();
-            pelvisRotation = pelvis.localEulerAngles;
-        }
-
-        protected override void Drag()
-        {
-            if (CurrentDragType == DragType.None) return;
-
-            if (isPlaying) meido.IsStop = true;
-
-            Vector3 pos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z);
-            Vector3 vec31 = Input.mousePosition - mousePos;
-            Transform t = GameMain.Instance.MainCamera.gameObject.transform;
-            Vector3 vec32 = t.TransformDirection(Vector3.right);
-            Vector3 vec33 = t.TransformDirection(Vector3.forward);
-
-            if (CurrentDragType == DragType.RotLocalXZ)
-            {
-                pelvis.localEulerAngles = pelvisRotation;
-                pelvis.RotateAround(pelvis.position, new Vector3(vec32.x, 0.0f, vec32.z), vec31.y / 4f);
-                pelvis.RotateAround(pelvis.position, new Vector3(vec33.x, 0.0f, vec33.z), vec31.x / 6f);
-            }
-
-            if (CurrentDragType == DragType.RotLocalY)
-            {
-                pelvis.localEulerAngles = pelvisRotation;
-                pelvis.localRotation = Quaternion.Euler(pelvis.localEulerAngles)
-                    * Quaternion.AngleAxis(vec31.x / 3f, Vector3.right);
-            }
-        }
-    }
-}

+ 148 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragPointChain.cs

@@ -0,0 +1,148 @@
+using System;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    internal class DragPointChain : DragPointMeido
+    {
+        private readonly TBody.IKCMO IK = new TBody.IKCMO();
+        private Transform[] ikChain;
+        private Quaternion[] jointRotation = new Quaternion[3];
+        private int foot = 1;
+        private bool isLower = false;
+        private bool isMiddle = false;
+        private bool isUpper = false;
+        private bool isMune = false;
+
+        public override void Set(Transform lower)
+        {
+            base.Set(lower);
+            this.isMune = lower.name.StartsWith("Mune");
+            this.foot = lower.name.EndsWith("Foot") ? -1 : 1;
+            this.isLower = lower.name.EndsWith("Hand") || foot == -1;
+            this.isMiddle = lower.name.EndsWith("Calf") || lower.name.EndsWith("Forearm");
+            this.isUpper = !(isMiddle || isLower) && !isMune;
+            this.ikChain = new Transform[] {
+                lower.parent,
+                lower.parent,
+                lower
+            };
+            if (lower.name.EndsWith("Hand")) ikChain[0] = ikChain[0].parent;
+        }
+
+        private void InitializeRotation()
+        {
+            for (int i = 0; i < jointRotation.Length; i++)
+            {
+                jointRotation[i] = ikChain[i].localRotation;
+            }
+        }
+
+        protected override void ApplyDragType()
+        {
+            // TODO: All the dragpoints
+            DragType current = CurrentDragType;
+            bool isBone = IsBone;
+            if (CurrentDragType == DragType.Ignore) ApplyProperties();
+            else if (current == DragType.RotLocalXZ)
+            {
+                if (isLower) ApplyProperties(!isBone, false, isBone);
+                else ApplyProperties();
+            }
+            else if (current == DragType.RotLocalY)
+            {
+                if (isLower || isMiddle) ApplyProperties(!isBone, false, false);
+                else if (isUpper) ApplyProperties(false, false, isBone);
+                else ApplyProperties();
+            }
+            else if (current == DragType.RotY)
+            {
+                if (isMune) ApplyProperties(true, false, false);
+                else if (isMiddle) ApplyProperties(false, false, isBone);
+                else ApplyProperties();
+            }
+            else if (current == DragType.MoveXZ)
+            {
+                if (isLower) ApplyProperties(true, isBone, false);
+                else ApplyProperties();
+            }
+            else ApplyProperties(!isMune, (isBone && !isMune), false);
+        }
+
+        protected override void UpdateDragType()
+        {
+            bool control = Utility.GetModKey(Utility.ModKey.Control);
+            bool alt = Utility.GetModKey(Utility.ModKey.Alt);
+
+            if (Input.GetKey(KeyCode.Space) || OtherDragType())
+            {
+                CurrentDragType = DragType.Ignore;
+            }
+            else if (control && alt)
+            {
+                // mune
+                CurrentDragType = DragType.RotY;
+            }
+            else if (control)
+            {
+                CurrentDragType = DragType.MoveXZ;
+            }
+            else if (alt)
+            {
+                bool shift = Utility.GetModKey(Utility.ModKey.Shift);
+                CurrentDragType = shift ? DragType.RotLocalY : DragType.RotLocalXZ;
+            }
+            else
+            {
+                CurrentDragType = DragType.None;
+            }
+        }
+
+        protected override void OnMouseDown()
+        {
+            base.OnMouseDown();
+
+            if (isMune) meido.SetMune(true);
+
+            InitializeRotation();
+
+            InitializeIK(IK, ikChain[jointUpper], ikChain[jointMiddle], ikChain[jointLower]);
+        }
+
+        protected override void OnDoubleClick()
+        {
+            if (isMune && CurrentDragType == DragType.RotY) meido.SetMune();
+        }
+
+        protected override void Drag()
+        {
+            if (isPlaying) meido.IsStop = true;
+
+            bool altRotation = CurrentDragType == DragType.MoveXZ || CurrentDragType == DragType.RotY;
+
+            if ((CurrentDragType == DragType.None) || altRotation)
+            {
+                int upperJoint = altRotation ? jointMiddle : jointUpper;
+
+                Porc(IK, ikChain[upperJoint], ikChain[jointMiddle], ikChain[jointLower]);
+
+                InitializeRotation();
+            }
+
+            Vector3 mouseDelta = MouseDelta();
+
+            if (CurrentDragType == DragType.RotLocalY)
+            {
+                int joint = this.isMiddle ? jointUpper : jointLower;
+                ikChain[joint].localRotation = jointRotation[joint];
+                ikChain[joint].Rotate(Vector3.right * (-mouseDelta.x / 1.5f));
+            }
+            if (CurrentDragType == DragType.RotLocalXZ)
+            {
+                ikChain[jointLower].localRotation = jointRotation[jointLower];
+                ikChain[jointLower].Rotate(Vector3.up * (foot * mouseDelta.x / 1.5f));
+                ikChain[jointLower].Rotate(Vector3.forward * (foot * mouseDelta.y / 1.5f));
+            }
+        }
+    }
+}

+ 94 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragPointFinger.cs

@@ -0,0 +1,94 @@
+using System;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    internal class DragPointFinger : DragPointMeido
+    {
+        private readonly TBody.IKCMO IK = new TBody.IKCMO();
+        private Transform[] ikChain;
+        private Quaternion[] jointRotation = new Quaternion[2];
+        private bool baseFinger;
+
+        public override void Set(Transform finger)
+        {
+            base.Set(finger);
+            string parentName = finger.parent.name.Split(' ')[2];
+            // Base finger names have the form 'FingerN' or 'ToeN' where N is a natural number
+            this.baseFinger = (parentName.Length == 7) || (parentName.Length == 4);
+            this.ikChain = new Transform[2] {
+                finger.parent,
+                finger
+            };
+        }
+
+        private void SetRotation(int joint)
+        {
+            Vector3 rotation = jointRotation[joint].eulerAngles;
+            rotation.z = ikChain[joint].localEulerAngles.z;
+            ikChain[joint].localRotation = Quaternion.Euler(rotation);
+        }
+
+        protected override void ApplyDragType()
+        {
+            if (baseFinger && CurrentDragType == DragType.RotLocalY)
+            {
+                ApplyProperties(true, true, false);
+            }
+            else if (CurrentDragType == DragType.MoveXZ)
+            {
+                ApplyProperties(true, true, false);
+            }
+            else
+            {
+                ApplyProperties(false, false, false);
+            }
+        }
+
+        protected override void UpdateDragType()
+        {
+            if (Input.GetKey(KeyCode.Space))
+            {
+                CurrentDragType = Utility.GetModKey(Utility.ModKey.Shift)
+                    ? DragType.RotLocalY
+                    : DragType.MoveXZ;
+            }
+            else CurrentDragType = DragType.None;
+        }
+
+        protected override void OnMouseDown()
+        {
+            base.OnMouseDown();
+            jointRotation[jointUpper] = ikChain[jointUpper].localRotation;
+            jointRotation[jointMiddle] = ikChain[jointMiddle].localRotation;
+            InitializeIK(IK, ikChain[jointUpper], ikChain[jointUpper], ikChain[jointMiddle]);
+        }
+
+        protected override void Drag()
+        {
+            if (isPlaying) meido.IsStop = true;
+
+            if (CurrentDragType == DragType.MoveXZ)
+            {
+                Porc(IK, ikChain[jointUpper], ikChain[jointUpper], ikChain[jointMiddle]);
+                if (!baseFinger)
+                {
+                    SetRotation(jointUpper);
+                    SetRotation(jointMiddle);
+                }
+                else
+                {
+                    jointRotation[jointUpper] = ikChain[jointUpper].localRotation;
+                    jointRotation[jointMiddle] = ikChain[jointMiddle].localRotation;
+                }
+            }
+            else if (CurrentDragType == DragType.RotLocalY)
+            {
+                Vector3 mouseDelta = MouseDelta();
+
+                ikChain[jointUpper].localRotation = jointRotation[jointUpper];
+                ikChain[jointUpper].Rotate(Vector3.right * (mouseDelta.x / 1.5f));
+            }
+        }
+    }
+}

+ 121 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragPointHead.cs

@@ -0,0 +1,121 @@
+using System;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    internal class DragPointHead : DragPointMeido
+    {
+        TBody body;
+        private Quaternion headRotation;
+        private Vector3 eyeRotationL;
+        private Vector3 eyeRotationR;
+        private Quaternion defEyeRotL;
+        private Quaternion defEyeRotR;
+        public event EventHandler Select;
+        public bool IsIK { get; set; }
+
+        public override void Set(Transform myObject)
+        {
+            base.Set(myObject);
+            this.body = this.maid.body0;
+            this.defEyeRotL = this.maid.body0.quaDefEyeL;
+            this.defEyeRotR = this.maid.body0.quaDefEyeR;
+        }
+
+        protected override void ApplyDragType()
+        {
+            if (IsBone)
+            {
+                DragType current = CurrentDragType;
+                bool active = current == DragType.MoveY || current == DragType.MoveXZ || current == DragType.Select;
+                ApplyProperties(active, false, false);
+            }
+            else ApplyProperties(CurrentDragType != DragType.None, false, false);
+        }
+
+        protected override void UpdateDragType()
+        {
+            bool shift = Utility.GetModKey(Utility.ModKey.Shift);
+            if (Utility.GetModKey(Utility.ModKey.Alt) && Utility.GetModKey(Utility.ModKey.Control))
+            {
+                // eyes
+                CurrentDragType = shift ? DragType.MoveY : DragType.MoveXZ;
+            }
+            else if (Utility.GetModKey(Utility.ModKey.Alt))
+            {
+                // head
+                CurrentDragType = shift ? DragType.RotLocalY : DragType.RotLocalXZ;
+            }
+            else if (Input.GetKey(KeyCode.A))
+            {
+                CurrentDragType = DragType.Select;
+            }
+            else
+            {
+                CurrentDragType = DragType.None;
+            }
+        }
+
+        protected override void OnMouseDown()
+        {
+            base.OnMouseDown();
+
+            if (CurrentDragType == DragType.Select) Select?.Invoke(this, EventArgs.Empty);
+
+            headRotation = MyObject.rotation;
+
+            eyeRotationL = body.quaDefEyeL.eulerAngles;
+            eyeRotationR = body.quaDefEyeR.eulerAngles;
+        }
+
+        protected override void OnDoubleClick()
+        {
+            if (CurrentDragType == DragType.MoveXZ || CurrentDragType == DragType.MoveY)
+            {
+                body.quaDefEyeL = defEyeRotL;
+                body.quaDefEyeR = defEyeRotR;
+            }
+            else if (CurrentDragType == DragType.RotLocalY || CurrentDragType == DragType.RotLocalXZ)
+            {
+                meido.IsFreeLook = !meido.IsFreeLook;
+            }
+        }
+
+        protected override void Drag()
+        {
+            if (IsIK) return;
+
+            if (!(CurrentDragType == DragType.MoveXZ || CurrentDragType == DragType.MoveY))
+            {
+                if (isPlaying) meido.IsStop = true;
+            }
+
+            Vector3 mouseDelta = MouseDelta();
+
+            if (CurrentDragType == DragType.RotLocalXZ)
+            {
+                MyObject.rotation = headRotation;
+                MyObject.Rotate(camera.transform.forward, -mouseDelta.x / 3f, Space.World);
+                MyObject.Rotate(camera.transform.right, mouseDelta.y / 3f, Space.World);
+            }
+
+            if (CurrentDragType == DragType.RotLocalY)
+            {
+                MyObject.rotation = headRotation;
+                MyObject.Rotate(Vector3.right * mouseDelta.x / 3f);
+            }
+
+            if (CurrentDragType == DragType.MoveXZ || CurrentDragType == DragType.MoveY)
+            {
+                int inv = CurrentDragType == DragType.MoveY ? -1 : 1;
+
+                body.quaDefEyeL.eulerAngles = new Vector3(
+                    eyeRotationL.x, eyeRotationL.y - mouseDelta.x / 10f, eyeRotationL.z - mouseDelta.y / 10f
+                );
+                body.quaDefEyeR.eulerAngles = new Vector3(
+                    eyeRotationR.x, eyeRotationR.y + inv * mouseDelta.x / 10f, eyeRotationR.z + mouseDelta.y / 10f
+                );
+            }
+        }
+    }
+}

+ 62 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragPointPelvis.cs

@@ -0,0 +1,62 @@
+using System;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    internal class DragPointPelvis : DragPointMeido
+    {
+        private Quaternion pelvisRotation;
+
+        protected override void ApplyDragType()
+        {
+            if (CurrentDragType == DragType.Ignore) ApplyProperties();
+            else if (IsBone) ApplyProperties(false, false, false);
+            else ApplyProperties(CurrentDragType != DragType.None, false, false);
+        }
+
+        protected override void UpdateDragType()
+        {
+            if (Input.GetKey(KeyCode.Space) || OtherDragType())
+            {
+                CurrentDragType = DragType.Ignore;
+            }
+            else if (Utility.GetModKey(Utility.ModKey.Alt) && !Utility.GetModKey(Utility.ModKey.Control))
+            {
+                bool shift = Utility.GetModKey(Utility.ModKey.Shift);
+                CurrentDragType = shift ? DragType.RotLocalY : DragType.RotLocalXZ;
+            }
+            else
+            {
+                CurrentDragType = DragType.None;
+            }
+        }
+
+        protected override void OnMouseDown()
+        {
+            base.OnMouseDown();
+            pelvisRotation = MyObject.rotation;
+        }
+
+        protected override void Drag()
+        {
+            if (CurrentDragType == DragType.None) return;
+
+            if (isPlaying) meido.IsStop = true;
+
+            Vector3 mouseDelta = MouseDelta();
+
+            if (CurrentDragType == DragType.RotLocalXZ)
+            {
+                MyObject.rotation = pelvisRotation;
+                MyObject.Rotate(camera.transform.forward, mouseDelta.x / 6f, Space.World);
+                MyObject.Rotate(camera.transform.right, mouseDelta.y / 4f, Space.World);
+            }
+
+            if (CurrentDragType == DragType.RotLocalY)
+            {
+                MyObject.rotation = pelvisRotation;
+                MyObject.Rotate(Vector3.right * (mouseDelta.x / 2.2f));
+            }
+        }
+    }
+}

+ 91 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragPointSpine.cs

@@ -0,0 +1,91 @@
+using System;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    internal class DragPointSpine : DragPointMeido
+    {
+        private Quaternion spineRotation;
+        private bool isHip = false;
+        private bool isThigh = false;
+
+        public override void Set(Transform spine)
+        {
+            base.Set(spine);
+            isHip = spine.name == "Bip01";
+            isThigh = spine.name.EndsWith("Thigh");
+        }
+
+        protected override void ApplyDragType()
+        {
+            DragType current = CurrentDragType;
+            if (IsBone && current != DragType.Ignore)
+            {
+                if (current == DragType.RotLocalXZ) ApplyProperties(false, false, isThigh);
+                else if (!isThigh && (current == DragType.MoveY)) ApplyProperties(isHip, isHip, !isHip);
+                else if (!isThigh && (current == DragType.RotLocalY)) ApplyProperties(!isHip, !isHip, isHip);
+                else ApplyProperties(!isThigh, !isThigh, false);
+            }
+            else ApplyProperties(false, false, false);
+        }
+
+        protected override void UpdateDragType()
+        {
+            bool shift = Utility.GetModKey(Utility.ModKey.Shift);
+            bool alt = Utility.GetModKey(Utility.ModKey.Alt);
+
+            if (Input.GetKey(KeyCode.Space) || OtherDragType())
+            {
+                CurrentDragType = DragType.Ignore;
+            }
+            else if (isThigh && alt && shift)
+            {
+                // gizmo thigh rotation
+                CurrentDragType = DragType.RotLocalXZ;
+            }
+            else if (alt)
+            {
+                CurrentDragType = DragType.Ignore;
+            }
+            else if (shift)
+            {
+                CurrentDragType = DragType.RotLocalY;
+            }
+            else if (Utility.GetModKey(Utility.ModKey.Control))
+            {
+                // hip y transform and spine gizmo rotation
+                CurrentDragType = DragType.MoveY;
+            }
+            else
+            {
+                CurrentDragType = DragType.None;
+            }
+        }
+
+        protected override void OnMouseDown()
+        {
+            base.OnMouseDown();
+            spineRotation = MyObject.rotation;
+        }
+
+        protected override void Drag()
+        {
+            if (isPlaying) meido.IsStop = true;
+
+            if (CurrentDragType == DragType.None)
+            {
+                Vector3 mouseDelta = MouseDelta();
+
+                MyObject.rotation = spineRotation;
+                MyObject.Rotate(camera.transform.forward, -mouseDelta.x / 4.5f, Space.World);
+                MyObject.Rotate(camera.transform.right, mouseDelta.y / 3f, Space.World);
+            }
+
+            if (CurrentDragType == DragType.MoveY)
+            {
+                Vector3 cursorPosition = CursorPosition();
+                MyObject.position = new Vector3(MyObject.position.x, cursorPosition.y, MyObject.position.z);
+            }
+        }
+    }
+}

+ 87 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragPointTorso.cs

@@ -0,0 +1,87 @@
+using System;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    internal class DragPointTorso : DragPointMeido
+    {
+        private static readonly float[] blah = new[] { 0.03f, 0.1f, 0.09f, 0.07f };
+        private static readonly float[] something = new[] { 0.08f, 0.15f };
+        private Transform[] spine = new Transform[4];
+        private Quaternion[] spineRotation = new Quaternion[4];
+
+        public override void Set(Transform spine1a)
+        {
+            base.Set(spine1a);
+            Transform spine = spine1a;
+            for (int i = 0; i < this.spine.Length; i++)
+            {
+                this.spine[i] = spine;
+                spine = spine.parent;
+            }
+        }
+
+        protected override void ApplyDragType()
+        {
+            if (CurrentDragType == DragType.Ignore) ApplyProperties();
+            else if (IsBone) ApplyProperties(false, false, false);
+            else ApplyProperties(CurrentDragType != DragType.None, false, false);
+        }
+
+        protected override void UpdateDragType()
+        {
+            if (Input.GetKey(KeyCode.Space) || OtherDragType())
+            {
+                CurrentDragType = DragType.Ignore;
+            }
+            else if (Utility.GetModKey(Utility.ModKey.Alt) && !Utility.GetModKey(Utility.ModKey.Control))
+            {
+                bool shift = Utility.GetModKey(Utility.ModKey.Shift);
+                CurrentDragType = shift ? DragType.RotLocalY : DragType.RotLocalXZ;
+            }
+            else
+            {
+                CurrentDragType = DragType.None;
+            }
+        }
+
+        protected override void OnMouseDown()
+        {
+            base.OnMouseDown();
+            for (int i = 0; i < spine.Length; i++)
+            {
+                spineRotation[i] = spine[i].localRotation;
+            }
+        }
+
+        protected override void Drag()
+        {
+            if (CurrentDragType == DragType.None) return;
+
+            if (isPlaying) meido.IsStop = true;
+
+            Vector3 mouseDelta = MouseDelta();
+
+            if (CurrentDragType == DragType.RotLocalXZ)
+            {
+                for (int i = 0; i < spine.Length; i++)
+                {
+                    spine[i].localRotation = spineRotation[i];
+                    spine[i].Rotate(
+                        camera.transform.forward, -mouseDelta.x / 1.5f * blah[i], Space.World
+                    );
+                    spine[i].Rotate(camera.transform.right, mouseDelta.y * blah[i], Space.World);
+                }
+            }
+
+            if (CurrentDragType == DragType.RotLocalY)
+            {
+                for (int i = 0; i < spine.Length; i++)
+                {
+                    spine[i].localRotation = spineRotation[i];
+                    spine[i].Rotate(Vector3.right * (mouseDelta.x / 1.5f * something[i / 2]));
+                }
+            }
+        }
+    }
+}

+ 0 - 82
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragSpine.cs

@@ -1,82 +0,0 @@
-using System;
-using UnityEngine;
-
-namespace COM3D2.MeidoPhotoStudio.Plugin
-{
-    internal class DragSpine : BaseDrag
-    {
-        private Transform spine;
-        private Vector3 rotate;
-        private Vector3 off;
-        private Vector3 off2;
-        private bool isHip;
-
-        public DragSpine Initialize(
-            Transform spine, bool isHip,
-            Meido meido, Func<Vector3> position, Func<Vector3> rotation
-        )
-        {
-            base.Initialize(meido, position, rotation);
-            this.spine = spine;
-            this.isHip = isHip;
-
-            InitializeGizmo(this.spine);
-            return this;
-        }
-
-        protected override void GetDragType()
-        {
-            if (isHip && Utility.GetModKey(Utility.ModKey.Control))
-            {
-                CurrentDragType = DragType.MoveY;
-            }
-            else
-            {
-                CurrentDragType = DragType.None;
-            }
-        }
-
-        protected override void InitializeDrag()
-        {
-            base.InitializeDrag();
-            rotate = spine.localEulerAngles;
-
-            if (isHip)
-            {
-                off = transform.position - Camera.main.ScreenToWorldPoint(
-                    new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z)
-                );
-                off2 = new Vector3(
-                    transform.position.x - spine.position.x,
-                    transform.position.y - spine.position.y,
-                    transform.position.z - spine.position.z
-                );
-            }
-        }
-
-        protected override void Drag()
-        {
-            if (isPlaying) meido.IsStop = true;
-
-            if (CurrentDragType == DragType.None)
-            {
-                Vector3 vec31 = Input.mousePosition - mousePos;
-                Transform t = GameMain.Instance.MainCamera.gameObject.transform;
-                Vector3 vec32 = t.TransformDirection(Vector3.right);
-                Vector3 vec33 = t.TransformDirection(Vector3.forward);
-
-                spine.localEulerAngles = rotate;
-                spine.RotateAround(spine.position, new Vector3(vec32.x, 0.0f, vec32.z), vec31.y / 3f);
-                spine.RotateAround(spine.position, new Vector3(vec33.x, 0.0f, vec33.z), (-vec31.x / 4.5f));
-            }
-
-            if (CurrentDragType == DragType.MoveY)
-            {
-                Vector3 pos = Camera.main.ScreenToWorldPoint(
-                    new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z)
-                ) + off - off2;
-                spine.position = new Vector3(spine.position.x, pos.y, spine.position.z);
-            }
-        }
-    }
-}

+ 0 - 91
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/IK/DragTorso.cs

@@ -1,91 +0,0 @@
-using System;
-using UnityEngine;
-
-namespace COM3D2.MeidoPhotoStudio.Plugin
-{
-    internal class DragTorso : BaseDrag
-    {
-        private Transform[] spine;
-        private Vector3[] spineRotation = new Vector3[4];
-
-        public DragTorso Initialize(Transform[] spine, Meido meido, Func<Vector3> position, Func<Vector3> rotation)
-        {
-            base.Initialize(meido, position, rotation);
-            this.spine = spine;
-            return this;
-        }
-
-        protected override void GetDragType()
-        {
-            bool shift = Input.GetKey(KeyCode.LeftShift);
-            if (Input.GetKey(KeyCode.LeftAlt))
-            {
-                CurrentDragType = shift ? DragType.RotLocalY : DragType.RotLocalXZ;
-            }
-            else
-            {
-                CurrentDragType = DragType.None;
-            }
-        }
-
-        protected override void InitializeDrag()
-        {
-            base.InitializeDrag();
-
-            for (int i = 0; i < spine.Length; i++)
-            {
-                spineRotation[i] = spine[i].localEulerAngles;
-            }
-        }
-
-        protected override void Drag()
-        {
-            if (CurrentDragType == DragType.None) return;
-
-            if (isPlaying) meido.IsStop = true;
-
-            Vector3 pos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z);
-            Vector3 vec31 = Input.mousePosition - mousePos;
-            Transform t = GameMain.Instance.MainCamera.gameObject.transform;
-            Vector3 vec32 = t.TransformDirection(Vector3.right);
-            Vector3 vec33 = t.TransformDirection(Vector3.forward);
-
-            if (CurrentDragType == DragType.RotLocalXZ)
-            {
-                for (int i = 0; i < 4; i++)
-                {
-                    spine[i].localEulerAngles = spineRotation[i];
-                }
-
-                float num1 = 1.5f;
-                float num2 = 1f;
-                float num3 = 0.03f;
-                float num4 = 0.1f;
-                float num5 = 0.09f;
-                float num6 = 0.07f;
-                spine[0].RotateAround(spine[0].position, new Vector3(vec32.x, 0f, vec32.z), vec31.y / num2 * num3);
-                spine[0].RotateAround(spine[0].position, new Vector3(vec33.x, 0f, vec33.z), -vec31.x / num1 * num3);
-                spine[1].RotateAround(spine[1].position, new Vector3(vec32.x, 0f, vec32.z), vec31.y / num2 * num4);
-                spine[1].RotateAround(spine[1].position, new Vector3(vec33.x, 0f, vec33.z), -vec31.x / num1 * num4);
-                spine[2].RotateAround(spine[2].position, new Vector3(vec32.x, 0f, vec32.z), vec31.y / num2 * num5);
-                spine[2].RotateAround(spine[2].position, new Vector3(vec33.x, 0f, vec33.z), -vec31.x / num1 * num5);
-                spine[3].RotateAround(spine[3].position, new Vector3(vec32.x, 0f, vec32.z), vec31.y / num2 * num6);
-                spine[3].RotateAround(spine[3].position, new Vector3(vec33.x, 0f, vec33.z), -vec31.x / num1 * num6);
-            }
-
-            if (CurrentDragType == DragType.RotLocalY)
-            {
-                for (int i = 0; i < 4; i++)
-                {
-                    spine[i].localEulerAngles = spineRotation[i];
-                }
-                spine[0].localRotation = Quaternion.Euler(spine[0].localEulerAngles)
-                    * Quaternion.AngleAxis(vec31.x / 1.5f * 0.08f, Vector3.right);
-                spine[2].localRotation = Quaternion.Euler(spine[2].localEulerAngles)
-                    * Quaternion.AngleAxis(vec31.x / 1.5f * 0.15f, Vector3.right);
-                spine[3].localRotation = Quaternion.Euler(spine[3].localEulerAngles)
-                    * Quaternion.AngleAxis(vec31.x / 1.5f * 0.15f, Vector3.right);
-            }
-        }
-    }
-}

+ 26 - 64
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/Meido.cs

@@ -20,7 +20,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         public string NameJP => $"{LastName}\n{FirstName}";
         public string NameEN => $"{FirstName}\n{LastName}";
         public int ActiveSlot { get; private set; }
-        private DragPointManager dragPointManager;
+        private MeidoDragPointManager dragPointManager;
         public event EventHandler<MeidoUpdateEventArgs> UpdateMeido;
         public event EventHandler BodyLoad;
         private bool isLoading = false;
@@ -33,18 +33,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 else dragPointManager.Active = value;
             }
         }
-        private bool isFreeLook;
-        public bool IsFreeLook
-        {
-            get => isFreeLook;
-            set
-            {
-                if (this.isFreeLook == value) return;
-                this.isFreeLook = value;
-                Maid.body0.trsLookTarget = this.isFreeLook ? null : GameMain.Instance.MainCamera.transform;
-                OnUpdateMeido();
-            }
-        }
         public bool IsStop
         {
             get
@@ -63,35 +51,31 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 }
             }
         }
-        private bool isBone = false;
+        // private bool isBone = false;
         public bool IsBone
         {
-            get => isBone;
+            get => dragPointManager?.IsBone ?? false;
             set
             {
-                if (this.isBone == value) return;
-                this.isBone = value;
-                if (this.dragPointManager != null) this.dragPointManager.IsBone = this.isBone;
+                if (dragPointManager == null || value == dragPointManager.IsBone) return;
+                else dragPointManager.IsBone = value;
                 OnUpdateMeido();
             }
         }
-        public bool Visible
-        {
-            get => Maid.Visible;
-            set => Maid.Visible = value;
-        }
-        private PoseInfo cachedPose;
-        public PoseInfo CachedPose
-        {
-            get => cachedPose;
-            private set => cachedPose = value;
-        }
-        private string faceBlendSet = defaultFaceBlendSet;
-        public string FaceBlendSet
+        private bool isFreeLook;
+        public bool IsFreeLook
         {
-            get => faceBlendSet;
-            private set => faceBlendSet = value;
+            get => isFreeLook;
+            set
+            {
+                if (this.isFreeLook == value) return;
+                this.isFreeLook = value;
+                Maid.body0.trsLookTarget = this.isFreeLook ? null : GameMain.Instance.MainCamera.transform;
+                OnUpdateMeido();
+            }
         }
+        public PoseInfo CachedPose { get; private set; }
+        public string FaceBlendSet { get; private set; } = defaultFaceBlendSet;
 
         public Meido(int stockMaidIndex)
         {
@@ -114,10 +98,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                     isLoading = false;
                     OnBodyLoad();
                 }
-                return;
             }
-
-            dragPointManager.Update();
         }
 
         public Maid Load(int slot, int activeSlot)
@@ -145,26 +126,14 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 SetPose(defaultPose);
             }
 
-            if (dragPointManager == null)
-            {
-                dragPointManager = new DragPointManager(this);
-                dragPointManager.SelectMaid += OnMeidoSelect;
-            }
-            else
-            {
-                dragPointManager.Active = true;
-
-                this.IsIK = true;
-                this.IsStop = false;
-                this.IsBone = false;
-            }
+            dragPointManager = new MeidoDragPointManager(this);
+            dragPointManager.SelectMaid += OnMeidoSelect;
 
             this.IsFreeLook = false;
             Maid.body0.boHeadToCam = true;
             Maid.body0.boEyeToCam = true;
             Maid.body0.SetBoneHitHeightY(-1000f);
 
-
             return Maid;
         }
 
@@ -184,21 +153,17 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
             Maid.Visible = false;
 
-            if (dragPointManager != null) dragPointManager.Active = false;
-
-            this.IsIK = false;
-            this.IsStop = false;
-            this.IsBone = false;
-        }
-
-        public void Deactivate()
-        {
-            Unload();
             if (dragPointManager != null)
             {
                 dragPointManager.Destroy();
                 dragPointManager.SelectMaid -= OnMeidoSelect;
+                dragPointManager = null;
             }
+        }
+
+        public void Deactivate()
+        {
+            Unload();
 
             Maid.SetPos(Vector3.zero);
             Maid.SetRot(Vector3.zero);
@@ -321,10 +286,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             body.FixVisibleFlag(false);
         }
 
-        public Transform GetBoneTransform(DragPointManager.AttachPoint point)
-        {
-            return this.dragPointManager?.GetAttachPointTransform(point);
-        }
+        public Transform GetBoneTransform(AttachPoint point) => this.dragPointManager?.GetAttachPointTransform(point);
 
         private void OnBodyLoad()
         {

+ 529 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/MeidoDragPointManager.cs

@@ -0,0 +1,529 @@
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    internal enum AttachPoint
+    {
+        None, Head, Neck, UpperArmL, UpperArmR, ForearmL, ForearmR, MuneL, MuneR, HandL, HandR,
+        Pelvis, ThighL, ThighR, CalfL, CalfR, FootL, FootR
+    }
+
+    internal class MeidoDragPointManager
+    {
+        private enum Bone
+        {
+            Head, HeadNub, ClavicleL, ClavicleR,
+            UpperArmL, UpperArmR, ForearmL, ForearmR,
+            HandL, HandR, IKHandL, IKHandR,
+            MuneL, MuneSubL, MuneR, MuneSubR,
+            Neck, Spine, Spine0a, Spine1, Spine1a, ThighL, ThighR,
+            Pelvis, Hip,
+            CalfL, CalfR, FootL, FootR,
+            // Dragpoint specific
+            Cube, Body, Torso,
+            // Fingers
+            Finger0L, Finger01L, Finger02L, Finger0NubL,
+            Finger1L, Finger11L, Finger12L, Finger1NubL,
+            Finger2L, Finger21L, Finger22L, Finger2NubL,
+            Finger3L, Finger31L, Finger32L, Finger3NubL,
+            Finger4L, Finger41L, Finger42L, Finger4NubL,
+            Finger0R, Finger01R, Finger02R, Finger0NubR,
+            Finger1R, Finger11R, Finger12R, Finger1NubR,
+            Finger2R, Finger21R, Finger22R, Finger2NubR,
+            Finger3R, Finger31R, Finger32R, Finger3NubR,
+            Finger4R, Finger41R, Finger42R, Finger4NubR,
+            // Toes
+            Toe0L, Toe01L, Toe0NubL,
+            Toe1L, Toe11L, Toe1NubL,
+            Toe2L, Toe21L, Toe2NubL,
+            Toe0R, Toe01R, Toe0NubR,
+            Toe1R, Toe11R, Toe1NubR,
+            Toe2R, Toe21R, Toe2NubR
+        }
+        private static readonly Dictionary<AttachPoint, Bone> PointToBone = new Dictionary<AttachPoint, Bone>()
+        {
+            [AttachPoint.Head] = Bone.Head,
+            [AttachPoint.Neck] = Bone.HeadNub,
+            [AttachPoint.UpperArmL] = Bone.UpperArmL,
+            [AttachPoint.UpperArmR] = Bone.UpperArmR,
+            [AttachPoint.ForearmL] = Bone.ForearmL,
+            [AttachPoint.ForearmR] = Bone.ForearmR,
+            [AttachPoint.MuneL] = Bone.MuneL,
+            [AttachPoint.MuneR] = Bone.MuneR,
+            [AttachPoint.HandL] = Bone.HandL,
+            [AttachPoint.HandR] = Bone.HandR,
+            [AttachPoint.Pelvis] = Bone.Pelvis,
+            [AttachPoint.ThighL] = Bone.ThighL,
+            [AttachPoint.ThighR] = Bone.ThighR,
+            [AttachPoint.CalfL] = Bone.CalfL,
+            [AttachPoint.CalfR] = Bone.CalfR,
+            [AttachPoint.FootL] = Bone.FootL,
+            [AttachPoint.FootR] = Bone.FootR,
+        };
+        private static bool cubeActive;
+        public static bool CubeActive
+        {
+            get => cubeActive;
+            set
+            {
+                if (value != cubeActive)
+                {
+                    cubeActive = value;
+                    CubeActiveChange?.Invoke(null, EventArgs.Empty);
+                }
+            }
+        }
+        private static bool cubeSmall = false;
+        public static bool CubeSmall
+        {
+            get => cubeSmall;
+            set
+            {
+                if (value != cubeSmall)
+                {
+                    cubeSmall = value;
+                    CubeSmallChange?.Invoke(null, EventArgs.Empty);
+                }
+            }
+        }
+        private static EventHandler CubeActiveChange;
+        private static EventHandler CubeSmallChange;
+        private Meido meido;
+        private Maid maid;
+        private Dictionary<Bone, Transform> BoneTransform;
+        private Dictionary<Bone, DragPointMeido> DragPoints;
+        private DragPointBody dragBody;
+        private DragPointBody dragCube;
+        public event EventHandler<MeidoUpdateEventArgs> SelectMaid;
+        private bool isBone = false;
+        public bool IsBone
+        {
+            get => isBone;
+            set
+            {
+                if (isBone != value)
+                {
+                    isBone = value;
+                    foreach (DragPointMeido dragPoint in DragPoints.Values)
+                    {
+                        dragPoint.IsBone = isBone;
+                    }
+                }
+            }
+        }
+        private bool active = true;
+        public bool Active
+        {
+            get => active;
+            set
+            {
+                if (active != value)
+                {
+                    active = value;
+                    foreach (DragPointMeido dragPoint in DragPoints.Values)
+                    {
+                        dragPoint.gameObject.SetActive(active);
+                    }
+                    DragPointHead head = (DragPointHead)DragPoints[Bone.Head];
+                    head.gameObject.SetActive(true);
+                    head.IsIK = !active;
+                }
+            }
+        }
+
+        public MeidoDragPointManager(Meido meido)
+        {
+            this.meido = meido;
+            this.maid = meido.Maid;
+            this.meido.BodyLoad += Initialize;
+        }
+
+        public Transform GetAttachPointTransform(AttachPoint point)
+        {
+            if (point == AttachPoint.None) return null;
+            return BoneTransform[PointToBone[point]];
+        }
+
+        public void Destroy()
+        {
+            foreach (DragPointMeido dragPoint in DragPoints.Values)
+            {
+                GameObject.Destroy(dragPoint.gameObject);
+            }
+            GameObject.Destroy(dragCube.gameObject);
+            GameObject.Destroy(dragBody.gameObject);
+            BoneTransform.Clear();
+            DragPoints.Clear();
+            CubeActiveChange -= OnCubeActive;
+            CubeSmallChange -= OnCubeSmall;
+        }
+
+        private void Initialize(object sender, EventArgs args)
+        {
+            meido.BodyLoad -= Initialize;
+            CubeActiveChange += OnCubeActive;
+            CubeSmallChange += OnCubeSmall;
+            InitializeBones();
+            InitializeDragPoints();
+        }
+
+        private void InitializeDragPoints()
+        {
+            DragPoints = new Dictionary<Bone, DragPointMeido>();
+
+            dragCube = DragPoint.Make<DragPointBody>(
+                PrimitiveType.Cube, Vector3.one * 0.12f, DragPoint.Blue
+            );
+            dragCube.Initialize(() => maid.transform.position, () => Vector3.zero);
+            dragCube.Set(maid.transform);
+
+            dragCube.IsCube = true;
+            dragCube.ConstantScale = true;
+            dragCube.Select += OnSelectBody;
+            dragCube.EndScale += OnSetDragPointScale;
+            dragCube.gameObject.SetActive(CubeActive);
+
+            dragBody = DragPoint.Make<DragPointBody>(
+                PrimitiveType.Capsule, new Vector3(0.2f, 0.3f, 0.24f), DragPoint.LightBlue
+            );
+            dragBody.Initialize(
+                () => new Vector3(
+                    (BoneTransform[Bone.Hip].position.x + BoneTransform[Bone.Spine0a].position.x) / 2f,
+                    (BoneTransform[Bone.Spine1].position.y + BoneTransform[Bone.Spine0a].position.y) / 2f,
+                    (BoneTransform[Bone.Spine0a].position.z + BoneTransform[Bone.Hip].position.z) / 2f
+                ),
+                () => new Vector3(
+                    BoneTransform[Bone.Spine0a].eulerAngles.x,
+                    BoneTransform[Bone.Spine0a].eulerAngles.y,
+                    BoneTransform[Bone.Spine0a].eulerAngles.z + 90f
+                )
+            );
+            dragBody.Set(maid.transform);
+            dragBody.Select += OnSelectBody;
+            dragBody.EndScale += OnSetDragPointScale;
+
+            // Head Dragpoint
+            DragPointHead dragHead = DragPoint.Make<DragPointHead>(
+                PrimitiveType.Sphere, new Vector3(0.2f, 0.24f, 0.2f), DragPoint.LightBlue
+            );
+            dragHead.Initialize(meido,
+                () => new Vector3(
+                    BoneTransform[Bone.Head].position.x,
+                    (BoneTransform[Bone.Head].position.y * 1.2f + BoneTransform[Bone.HeadNub].position.y * 0.8f) / 2f,
+                    BoneTransform[Bone.Head].position.z
+                ),
+                () => new Vector3(
+                    BoneTransform[Bone.Head].eulerAngles.x,
+                    BoneTransform[Bone.Head].eulerAngles.y,
+                    BoneTransform[Bone.Head].eulerAngles.z + 90f
+                )
+            );
+            dragHead.Set(BoneTransform[Bone.Neck]);
+            dragHead.Select += OnSelectFace;
+
+            DragPoints[Bone.Head] = dragHead;
+
+            // Torso Dragpoint
+            Transform spineTrans1 = BoneTransform[Bone.Spine1];
+            Transform spineTrans2 = BoneTransform[Bone.Spine1a];
+
+            DragPointTorso dragTorso = DragPoint.Make<DragPointTorso>(
+                PrimitiveType.Capsule, new Vector3(0.2f, 0.19f, 0.24f), DragPoint.LightBlue
+            );
+            dragTorso.Initialize(meido,
+                () => new Vector3(
+                    spineTrans1.position.x,
+                    spineTrans2.position.y,
+                    spineTrans1.position.z - 0.05f
+                ),
+                () => new Vector3(
+                    spineTrans1.eulerAngles.x,
+                    spineTrans1.eulerAngles.y,
+                    spineTrans1.eulerAngles.z + 90f
+                )
+            );
+            dragTorso.Set(BoneTransform[Bone.Spine1a]);
+
+            DragPoints[Bone.Torso] = dragTorso;
+
+            // Pelvis Dragpoint
+            Transform pelvisTrans = BoneTransform[Bone.Pelvis];
+            Transform spineTrans = BoneTransform[Bone.Spine];
+
+            DragPointPelvis dragPelvis = DragPoint.Make<DragPointPelvis>(
+                PrimitiveType.Capsule, new Vector3(0.2f, 0.15f, 0.24f), DragPoint.LightBlue
+            );
+            dragPelvis.Initialize(meido,
+
+                () => new Vector3(
+                    pelvisTrans.position.x,
+                    (pelvisTrans.position.y + spineTrans.position.y) / 2f,
+                    pelvisTrans.position.z
+                ),
+                () => new Vector3(
+                    pelvisTrans.eulerAngles.x + 90f,
+                    pelvisTrans.eulerAngles.y + 90f,
+                    pelvisTrans.eulerAngles.z
+                )
+            );
+            dragPelvis.Set(BoneTransform[Bone.Pelvis]);
+
+            DragPoints[Bone.Pelvis] = dragPelvis;
+
+            InitializeMuneDragPoint(left: true);
+            InitializeMuneDragPoint(left: false);
+
+            DragPointChain[] armDragPointL = MakeIKChain(BoneTransform[Bone.HandL]);
+            DragPoints[Bone.UpperArmL] = armDragPointL[0];
+            DragPoints[Bone.ForearmL] = armDragPointL[1];
+            DragPoints[Bone.HandL] = armDragPointL[2];
+
+            DragPointChain[] armDragPointR = MakeIKChain(BoneTransform[Bone.HandR]);
+            DragPoints[Bone.UpperArmR] = armDragPointR[0];
+            DragPoints[Bone.ForearmR] = armDragPointR[1];
+            DragPoints[Bone.HandR] = armDragPointR[2];
+
+            DragPointChain[] legDragPointL = MakeIKChain(BoneTransform[Bone.FootL]);
+            DragPoints[Bone.CalfL] = legDragPointL[0];
+            DragPoints[Bone.FootL] = legDragPointL[1];
+
+            DragPointChain[] legDragPointR = MakeIKChain(BoneTransform[Bone.FootR]);
+            DragPoints[Bone.CalfR] = legDragPointR[0];
+            DragPoints[Bone.FootR] = legDragPointR[1];
+
+            InitializeSpineDragPoint(
+                Bone.Neck, Bone.Spine, Bone.Spine0a, Bone.Spine1, Bone.Spine1a, Bone.Hip, Bone.ThighL, Bone.ThighR
+            );
+
+            InitializeFingerDragPoint(Bone.Finger0L, Bone.Finger4R);
+            InitializeFingerDragPoint(Bone.Toe0L, Bone.Toe2R);
+        }
+
+        private void InitializeMuneDragPoint(bool left)
+        {
+            Bone mune = left ? Bone.MuneL : Bone.MuneR;
+            Bone sub = left ? Bone.MuneSubL : Bone.MuneSubR;
+            DragPointChain muneDragPoint = DragPoint.Make<DragPointChain>(
+                PrimitiveType.Sphere, Vector3.one * 0.12f, DragPoint.LightBlue
+            );
+            muneDragPoint.Initialize(meido,
+                () => (BoneTransform[mune].position + BoneTransform[sub].position) / 2f,
+                () => Vector3.zero
+            );
+            muneDragPoint.Set(BoneTransform[sub]);
+            DragPoints[mune] = muneDragPoint;
+        }
+
+        private DragPointChain[] MakeIKChain(Transform lower)
+        {
+            Vector3 limbDragPointSize = Vector3.one * 0.12f;
+            // Ignore Thigh transform when making a leg IK chain
+            bool isLeg = lower.name.EndsWith("Foot");
+            DragPointChain[] dragPoints = new DragPointChain[isLeg ? 2 : 3];
+            for (int i = dragPoints.Length - 1; i >= 0; i--)
+            {
+                Transform joint = lower;
+                dragPoints[i] = DragPoint.Make<DragPointChain>(
+                    PrimitiveType.Sphere, limbDragPointSize, DragPoint.LightBlue
+                );
+                dragPoints[i].Initialize(meido, () => joint.position, () => Vector3.zero);
+                dragPoints[i].Set(joint);
+                dragPoints[i].AddGizmo();
+                lower = lower.parent;
+            }
+            return dragPoints;
+        }
+
+        private void InitializeFingerDragPoint(Bone start, Bone end)
+        {
+            Vector3 fingerDragPointSize = Vector3.one * 0.015f;
+            int joints = BoneTransform[start].name.Split(' ')[2].StartsWith("Finger") ? 4 : 3;
+            for (Bone bone = start; bone <= end; bone += joints)
+            {
+                for (int i = 1; i < joints; i++)
+                {
+                    Transform trans = BoneTransform[bone + i];
+                    DragPointFinger chain = DragPoint.Make<DragPointFinger>(
+                        PrimitiveType.Sphere, fingerDragPointSize, DragPoint.Blue
+                    );
+                    chain.Initialize(meido, () => trans.position, () => Vector3.zero);
+                    chain.Set(trans);
+                    DragPoints[bone + i] = chain;
+                }
+            }
+        }
+
+        private void InitializeSpineDragPoint(params Bone[] bones)
+        {
+            Vector3 spineDragPointSize = Vector3.one * 0.045f;
+            foreach (Bone bone in bones)
+            {
+                Transform spine = BoneTransform[bone];
+                PrimitiveType primitive = bone == Bone.Hip ? PrimitiveType.Cube : PrimitiveType.Sphere;
+                DragPointSpine dragPoint = DragPoint.Make<DragPointSpine>(
+                    primitive, spineDragPointSize, DragPoint.LightBlue
+                );
+                dragPoint.Initialize(meido,
+                    () => spine.position,
+                    () => Vector3.zero
+                );
+                dragPoint.Set(spine);
+                dragPoint.AddGizmo();
+                DragPoints[bone] = dragPoint;
+            }
+        }
+
+        private void OnCubeActive(object sender, EventArgs args)
+        {
+            dragCube.gameObject.SetActive(CubeActive);
+        }
+
+        private void OnCubeSmall(object sender, EventArgs args)
+        {
+            dragCube.DragPointScale = CubeSmall ? DragPointGeneral.smallCube : 1f;
+        }
+
+        private void OnSetDragPointScale(object sender, EventArgs args)
+        {
+            this.SetDragPointScale(maid.transform.localScale.x);
+        }
+
+        private void OnSelectBody(object sender, EventArgs args)
+        {
+            SelectMaid?.Invoke(this, new MeidoUpdateEventArgs(meido.ActiveSlot, fromMaid: true, isBody: true));
+        }
+
+        private void OnSelectFace(object sender, EventArgs args)
+        {
+            SelectMaid?.Invoke(this, new MeidoUpdateEventArgs(meido.ActiveSlot, fromMaid: true, isBody: false));
+        }
+
+        private void SetDragPointScale(float scale)
+        {
+            foreach (DragPointMeido dragPoint in DragPoints.Values)
+            {
+                dragPoint.DragPointScale = scale;
+            }
+            dragBody.DragPointScale = scale;
+        }
+
+        private void InitializeBones()
+        {
+            // TODO: Move to external file somehow
+            Transform transform = maid.body0.m_Bones.transform;
+            BoneTransform = new Dictionary<Bone, Transform>()
+            {
+                [Bone.Head] = CMT.SearchObjName(transform, "Bip01 Head"),
+                [Bone.Neck] = CMT.SearchObjName(transform, "Bip01 Neck"),
+                [Bone.HeadNub] = CMT.SearchObjName(transform, "Bip01 HeadNub"),
+                [Bone.IKHandL] = CMT.SearchObjName(transform, "_IK_handL"),
+                [Bone.IKHandR] = CMT.SearchObjName(transform, "_IK_handR"),
+                [Bone.MuneL] = CMT.SearchObjName(transform, "Mune_L"),
+                [Bone.MuneSubL] = CMT.SearchObjName(transform, "Mune_L_sub"),
+                [Bone.MuneR] = CMT.SearchObjName(transform, "Mune_R"),
+                [Bone.MuneSubR] = CMT.SearchObjName(transform, "Mune_R_sub"),
+                [Bone.Pelvis] = CMT.SearchObjName(transform, "Bip01 Pelvis"),
+                [Bone.Hip] = CMT.SearchObjName(transform, "Bip01"),
+                [Bone.Spine] = CMT.SearchObjName(transform, "Bip01 Spine"),
+                [Bone.Spine0a] = CMT.SearchObjName(transform, "Bip01 Spine0a"),
+                [Bone.Spine1] = CMT.SearchObjName(transform, "Bip01 Spine1"),
+                [Bone.Spine1a] = CMT.SearchObjName(transform, "Bip01 Spine1a"),
+                [Bone.ClavicleL] = CMT.SearchObjName(transform, "Bip01 L Clavicle"),
+                [Bone.ClavicleR] = CMT.SearchObjName(transform, "Bip01 R Clavicle"),
+                [Bone.UpperArmL] = CMT.SearchObjName(transform, "Bip01 L UpperArm"),
+                [Bone.ForearmL] = CMT.SearchObjName(transform, "Bip01 L Forearm"),
+                [Bone.HandL] = CMT.SearchObjName(transform, "Bip01 L Hand"),
+                [Bone.UpperArmR] = CMT.SearchObjName(transform, "Bip01 R UpperArm"),
+                [Bone.ForearmR] = CMT.SearchObjName(transform, "Bip01 R Forearm"),
+                [Bone.HandR] = CMT.SearchObjName(transform, "Bip01 R Hand"),
+                [Bone.ThighL] = CMT.SearchObjName(transform, "Bip01 L Thigh"),
+                [Bone.CalfL] = CMT.SearchObjName(transform, "Bip01 L Calf"),
+                [Bone.FootL] = CMT.SearchObjName(transform, "Bip01 L Foot"),
+                [Bone.ThighR] = CMT.SearchObjName(transform, "Bip01 R Thigh"),
+                [Bone.CalfR] = CMT.SearchObjName(transform, "Bip01 R Calf"),
+                [Bone.FootR] = CMT.SearchObjName(transform, "Bip01 R Foot"),
+                // fingers
+                [Bone.Finger0L] = CMT.SearchObjName(transform, "Bip01 L Finger0"),
+                [Bone.Finger01L] = CMT.SearchObjName(transform, "Bip01 L Finger01"),
+                [Bone.Finger02L] = CMT.SearchObjName(transform, "Bip01 L Finger02"),
+                [Bone.Finger0NubL] = CMT.SearchObjName(transform, "Bip01 L Finger0Nub"),
+                [Bone.Finger1L] = CMT.SearchObjName(transform, "Bip01 L Finger1"),
+                [Bone.Finger11L] = CMT.SearchObjName(transform, "Bip01 L Finger11"),
+                [Bone.Finger12L] = CMT.SearchObjName(transform, "Bip01 L Finger12"),
+                [Bone.Finger1NubL] = CMT.SearchObjName(transform, "Bip01 L Finger1Nub"),
+                [Bone.Finger2L] = CMT.SearchObjName(transform, "Bip01 L Finger2"),
+                [Bone.Finger21L] = CMT.SearchObjName(transform, "Bip01 L Finger21"),
+                [Bone.Finger22L] = CMT.SearchObjName(transform, "Bip01 L Finger22"),
+                [Bone.Finger2NubL] = CMT.SearchObjName(transform, "Bip01 L Finger2Nub"),
+                [Bone.Finger3L] = CMT.SearchObjName(transform, "Bip01 L Finger3"),
+                [Bone.Finger31L] = CMT.SearchObjName(transform, "Bip01 L Finger31"),
+                [Bone.Finger32L] = CMT.SearchObjName(transform, "Bip01 L Finger32"),
+                [Bone.Finger3NubL] = CMT.SearchObjName(transform, "Bip01 L Finger3Nub"),
+                [Bone.Finger4L] = CMT.SearchObjName(transform, "Bip01 L Finger4"),
+                [Bone.Finger41L] = CMT.SearchObjName(transform, "Bip01 L Finger41"),
+                [Bone.Finger42L] = CMT.SearchObjName(transform, "Bip01 L Finger42"),
+                [Bone.Finger4NubL] = CMT.SearchObjName(transform, "Bip01 L Finger4Nub"),
+                [Bone.Finger0R] = CMT.SearchObjName(transform, "Bip01 R Finger0"),
+                [Bone.Finger01R] = CMT.SearchObjName(transform, "Bip01 R Finger01"),
+                [Bone.Finger02R] = CMT.SearchObjName(transform, "Bip01 R Finger02"),
+                [Bone.Finger0NubR] = CMT.SearchObjName(transform, "Bip01 R Finger0Nub"),
+                [Bone.Finger1R] = CMT.SearchObjName(transform, "Bip01 R Finger1"),
+                [Bone.Finger11R] = CMT.SearchObjName(transform, "Bip01 R Finger11"),
+                [Bone.Finger12R] = CMT.SearchObjName(transform, "Bip01 R Finger12"),
+                [Bone.Finger1NubR] = CMT.SearchObjName(transform, "Bip01 R Finger1Nub"),
+                [Bone.Finger2R] = CMT.SearchObjName(transform, "Bip01 R Finger2"),
+                [Bone.Finger21R] = CMT.SearchObjName(transform, "Bip01 R Finger21"),
+                [Bone.Finger22R] = CMT.SearchObjName(transform, "Bip01 R Finger22"),
+                [Bone.Finger2NubR] = CMT.SearchObjName(transform, "Bip01 R Finger2Nub"),
+                [Bone.Finger3R] = CMT.SearchObjName(transform, "Bip01 R Finger3"),
+                [Bone.Finger31R] = CMT.SearchObjName(transform, "Bip01 R Finger31"),
+                [Bone.Finger32R] = CMT.SearchObjName(transform, "Bip01 R Finger32"),
+                [Bone.Finger3NubR] = CMT.SearchObjName(transform, "Bip01 R Finger3Nub"),
+                [Bone.Finger4R] = CMT.SearchObjName(transform, "Bip01 R Finger4"),
+                [Bone.Finger41R] = CMT.SearchObjName(transform, "Bip01 R Finger41"),
+                [Bone.Finger42R] = CMT.SearchObjName(transform, "Bip01 R Finger42"),
+                [Bone.Finger4NubR] = CMT.SearchObjName(transform, "Bip01 R Finger4Nub"),
+                // Toes
+                [Bone.Toe0L] = CMT.SearchObjName(transform, "Bip01 L Toe0"),
+                [Bone.Toe01L] = CMT.SearchObjName(transform, "Bip01 L Toe01"),
+                [Bone.Toe0NubL] = CMT.SearchObjName(transform, "Bip01 L Toe0Nub"),
+                [Bone.Toe1L] = CMT.SearchObjName(transform, "Bip01 L Toe1"),
+                [Bone.Toe11L] = CMT.SearchObjName(transform, "Bip01 L Toe11"),
+                [Bone.Toe1NubL] = CMT.SearchObjName(transform, "Bip01 L Toe1Nub"),
+                [Bone.Toe2L] = CMT.SearchObjName(transform, "Bip01 L Toe2"),
+                [Bone.Toe21L] = CMT.SearchObjName(transform, "Bip01 L Toe21"),
+                [Bone.Toe2NubL] = CMT.SearchObjName(transform, "Bip01 L Toe2Nub"),
+                [Bone.Toe0R] = CMT.SearchObjName(transform, "Bip01 R Toe0"),
+                [Bone.Toe01R] = CMT.SearchObjName(transform, "Bip01 R Toe01"),
+                [Bone.Toe0NubR] = CMT.SearchObjName(transform, "Bip01 R Toe0Nub"),
+                [Bone.Toe1R] = CMT.SearchObjName(transform, "Bip01 R Toe1"),
+                [Bone.Toe11R] = CMT.SearchObjName(transform, "Bip01 R Toe11"),
+                [Bone.Toe1NubR] = CMT.SearchObjName(transform, "Bip01 R Toe1Nub"),
+                [Bone.Toe2R] = CMT.SearchObjName(transform, "Bip01 R Toe2"),
+                [Bone.Toe21R] = CMT.SearchObjName(transform, "Bip01 R Toe21"),
+                [Bone.Toe2NubR] = CMT.SearchObjName(transform, "Bip01 R Toe2Nub")
+            };
+        }
+    }
+
+    internal struct AttachPointInfo
+    {
+        public AttachPoint AttachPoint { get; }
+        public string MaidGuid { get; }
+        public int MaidIndex { get; }
+        public static AttachPointInfo Empty
+        {
+            get => new AttachPointInfo(AttachPoint.None, String.Empty, -1);
+        }
+
+        public AttachPointInfo(AttachPoint attachPoint, string maidGuid, int maidIndex)
+        {
+            this.AttachPoint = attachPoint;
+            this.MaidGuid = maidGuid;
+            this.MaidIndex = maidIndex;
+        }
+    }
+}