Browse Source

Fix drag point misalignment from maid body

Arm and finger bones are misaligned from the actual maid's body when the
maid's body is heavily modified through modslider. Modslider can be used
to make maids body parts much larger and smaller which affects the
position of the arm and finger bones.

This commit changes the drag point's target position from the bones to
the maid's body instead which results in the drag points aligning with
the maid's body perfectly.

These changes are very experimental and dirty.
habeebweeb 3 năm trước cách đây
mục cha
commit
7ee1224b53

+ 9 - 1
src/MeidoPhotoStudio.Plugin/DragPoint/CustomGizmo.cs

@@ -8,6 +8,8 @@ namespace MeidoPhotoStudio.Plugin
     {
         private static readonly Camera camera = GameMain.Instance.MainCamera.camera;
         private Transform target;
+        private bool hasAlternateTarget;
+        private Transform positionTransform;
         private readonly FieldInfo beSelectedType = Utility.GetFieldInfo<GizmoRender>("beSelectedType");
         private int SelectedType => (int)beSelectedType.GetValue(this);
         private static readonly FieldInfo is_drag_ = Utility.GetFieldInfo<GizmoRender>("is_drag_");
@@ -70,6 +72,12 @@ namespace MeidoPhotoStudio.Plugin
             return gizmo;
         }
 
+        public void SetAlternateTarget(Transform trans)
+        {
+            positionTransform = trans;
+            hasAlternateTarget = trans != null;
+        }
+
         public override void Update()
         {
             BeginUpdate();
@@ -130,7 +138,7 @@ namespace MeidoPhotoStudio.Plugin
         private void SetTransform()
         {
             Transform transform = this.transform;
-            transform.position = target.position;
+            transform.position = (hasAlternateTarget ? positionTransform : target).position;
             transform.localScale = Vector3.one;
             transform.rotation = gizmoMode switch
             {

+ 71 - 13
src/MeidoPhotoStudio.Plugin/Meido/MeidoDragPointManager.cs

@@ -452,28 +452,38 @@ namespace MeidoPhotoStudio.Plugin
             InitializeMuneDragPoint(left: true);
             InitializeMuneDragPoint(left: false);
 
-            DragPointLimb[] armDragPointL = MakeIKChain(BoneTransform[Bone.HandL]);
+            var armDragPointL = MakeArmChain(BoneTransform[Bone.HandL], meido);
             DragPoints[Bone.UpperArmL] = armDragPointL[0];
             DragPoints[Bone.ForearmL] = armDragPointL[1];
             DragPoints[Bone.HandL] = armDragPointL[2];
 
-            DragPointLimb[] armDragPointR = MakeIKChain(BoneTransform[Bone.HandR]);
+            var armDragPointR = MakeArmChain(BoneTransform[Bone.HandR], meido);
             DragPoints[Bone.UpperArmR] = armDragPointR[0];
             DragPoints[Bone.ForearmR] = armDragPointR[1];
             DragPoints[Bone.HandR] = armDragPointR[2];
 
-            DragPointLimb[] legDragPointL = MakeIKChain(BoneTransform[Bone.FootL]);
+            var legDragPointL = MakeLegChain(BoneTransform[Bone.FootL]);
             DragPoints[Bone.CalfL] = legDragPointL[0];
             DragPoints[Bone.FootL] = legDragPointL[1];
 
-            DragPointLimb[] legDragPointR = MakeIKChain(BoneTransform[Bone.FootR]);
+            var legDragPointR = MakeLegChain(BoneTransform[Bone.FootR]);
             DragPoints[Bone.CalfR] = legDragPointR[0];
             DragPoints[Bone.FootR] = legDragPointR[1];
 
             InitializeSpineDragPoint(SpineBones);
 
-            InitializeFingerDragPoint(Bone.Finger0L, Bone.Finger4R);
-            InitializeFingerDragPoint(Bone.Toe0L, Bone.Toe2R);
+            for (var bone = Bone.Finger4NubR; bone >= Bone.Finger0L; bone -= 4)
+            {
+                var i = 2;
+                var chain = MakeFingerChain(BoneTransform[bone], meido);
+
+                for (var joint = bone - 1; joint > bone - 4; joint--)
+                {
+                    DragPoints[joint] = chain[i];
+                    i--;
+                }
+            }
+            MakeToeChain(Bone.Toe0L, Bone.Toe2R);
         }
 
         private void InitializeMuneDragPoint(bool left)
@@ -489,13 +499,11 @@ namespace MeidoPhotoStudio.Plugin
             DragPoints[mune] = muneDragPoint;
         }
 
-        private DragPointLimb[] MakeIKChain(Transform lower)
+        private DragPointLimb[] MakeLegChain(Transform lower)
         {
             Vector3 limbDragPointSize = Vector3.one * 0.12f;
-            // Ignore Thigh transform when making a leg IK chain
-            bool isLeg = lower.name.EndsWith("Foot");
-            DragPointLimb[] dragPoints = new DragPointLimb[isLeg ? 2 : 3];
-            for (int i = dragPoints.Length - 1; i >= 0; i--)
+            DragPointLimb[] dragPoints = new DragPointLimb[2];
+            for (var i = dragPoints.Length - 1; i >= 0; i--)
             {
                 Transform joint = lower;
                 dragPoints[i] = DragPoint.Make<DragPointLimb>(PrimitiveType.Sphere, limbDragPointSize);
@@ -507,10 +515,36 @@ namespace MeidoPhotoStudio.Plugin
             return dragPoints;
         }
 
-        private void InitializeFingerDragPoint(Bone start, Bone end)
+        private static DragPointLimb[] MakeArmChain(Transform lower, Meido meido)
+        {
+            var limbDragPointSize = Vector3.one * 0.12f;
+
+            var realLower = CMT.SearchObjName(meido.Body.goSlot[0].obj_tr, lower.name, false);
+
+            var dragPoints = new DragPointLimb[3];
+
+            for (var i = dragPoints.Length - 1; i >= 0; i--)
+            {
+                var joint = lower;
+                var positionJoint = realLower;
+
+                dragPoints[i] = DragPoint.Make<DragPointLimb>(PrimitiveType.Sphere, limbDragPointSize);
+                dragPoints[i].Initialize(meido, () => positionJoint.position, () => Vector3.zero);
+                dragPoints[i].Set(joint);
+                dragPoints[i].AddGizmo();
+                dragPoints[i].Gizmo.SetAlternateTarget(positionJoint);
+
+                lower = lower.parent;
+                realLower = realLower.parent;
+            }
+
+            return dragPoints;
+        }
+
+        private void MakeToeChain(Bone start, Bone end)
         {
             Vector3 fingerDragPointSize = Vector3.one * 0.01f;
-            int joints = BoneTransform[start].name.Split(' ')[2].StartsWith("Finger") ? 4 : 3;
+            const int joints = 3;
             for (Bone bone = start; bone <= end; bone += joints)
             {
                 for (int i = 1; i < joints; i++)
@@ -524,6 +558,30 @@ namespace MeidoPhotoStudio.Plugin
             }
         }
 
+        private static DragPointFinger[] MakeFingerChain(Transform lower, Meido meido)
+        {
+            var fingerDragPointSize = Vector3.one * 0.01f;
+
+            var dragPoints = new DragPointFinger[3];
+
+            var realLower = CMT.SearchObjName(meido.Body.goSlot[0].obj_tr, lower.parent.name, false);
+
+            for (var i = dragPoints.Length - 1; i >= 0; i--)
+            {
+                var joint = lower;
+                var positionJoint = realLower;
+
+                dragPoints[i] = DragPoint.Make<DragPointFinger>(PrimitiveType.Sphere, fingerDragPointSize);
+                dragPoints[i].Initialize(meido, () => positionJoint.position, () => Vector3.zero);
+                dragPoints[i].Set(joint);
+
+                lower = lower.parent;
+                realLower = realLower.parent;
+            }
+
+            return dragPoints;
+        }
+
         private void InitializeSpineDragPoint(params Bone[] bones)
         {
             Vector3 spineDragPointSize = DragPointMeido.boneScale;