Browse Source

Update meido deserialization for MM scenes

Changes were made to handle cases where only 64 points of data was
saved for maids.
habeebweeb 3 năm trước cách đây
mục cha
commit
353a7fc81b

+ 56 - 18
src/MeidoPhotoStudio.Plugin/Meido/MeidoDragPointManager.cs

@@ -144,28 +144,66 @@ namespace MeidoPhotoStudio.Plugin
 
         public MeidoDragPointManager(Meido meido) => this.meido = meido;
 
-        public void Deserialize(BinaryReader binaryReader)
+        public void Deserialize(BinaryReader reader)
         {
-            Bone[] bones = {
-                Bone.Hip, Bone.Pelvis, Bone.Spine, Bone.Spine0a, Bone.Spine1, Bone.Spine1a, Bone.Neck,
-                Bone.ClavicleL, Bone.ClavicleR, Bone.UpperArmL, Bone.UpperArmR, Bone.ForearmL, Bone.ForearmR,
-                Bone.ThighL, Bone.ThighR, Bone.CalfL, Bone.CalfR, Bone.MuneL, Bone.MuneR, Bone.MuneSubL, Bone.MuneSubR,
-                Bone.HandL, Bone.HandR, Bone.FootL, Bone.FootR
-            };
-            int localRotationIndex = Array.IndexOf(bones, Bone.CalfR);
-            for (Bone bone = Bone.Finger0L; bone <= Bone.Toe2NubR; ++bone)
-            {
-                BoneTransform[bone].localRotation = binaryReader.ReadQuaternion();
-            }
-            for (int i = 0; i < bones.Length; i++)
+            var sixtyFourFlag = reader.ReadBoolean();
+            var upperBone = sixtyFourFlag ? Bone.Finger4NubR : Bone.Toe2NubR;
+
+            // finger rotations. Toe rotations as well if sixtyFourFlag is false
+            for (var bone = Bone.Finger0L; bone <= upperBone; ++bone)
+                BoneTransform[bone].localRotation = reader.ReadQuaternion();
+
+            var bones = sixtyFourFlag ? new[]
+                {
+                    Bone.Pelvis, Bone.Spine, Bone.Spine0a, Bone.Spine1, Bone.Spine1a, Bone.Neck, Bone.UpperArmL,
+                    Bone.UpperArmR, Bone.ForearmL, Bone.ForearmR, Bone.ThighL, Bone.ThighR, Bone.CalfL, Bone.CalfR,
+                    Bone.HandL, Bone.HandR, Bone.FootL, Bone.FootR,
+                }
+                : new[]
+                {
+                    Bone.Hip, Bone.Pelvis, Bone.Spine, Bone.Spine0a, Bone.Spine1, Bone.Spine1a, Bone.Neck,
+                    Bone.ClavicleL, Bone.ClavicleR, Bone.UpperArmL, Bone.UpperArmR, Bone.ForearmL, Bone.ForearmR,
+                    Bone.ThighL, Bone.ThighR, Bone.CalfL, Bone.CalfR, Bone.MuneL, Bone.MuneR, Bone.MuneSubL,
+                    Bone.MuneSubR, Bone.HandL, Bone.HandR, Bone.FootL, Bone.FootR,
+                };
+
+            var localRotationIndex = Array.IndexOf(bones, Bone.CalfR);
+
+            for (var i = 0; i < bones.Length; i++)
             {
-                Bone bone = bones[i];
-                Quaternion rotation = binaryReader.ReadQuaternion();
-                if (i > localRotationIndex) BoneTransform[bone].localRotation = rotation;
-                else BoneTransform[bone].rotation = rotation;
+                var bone = bones[i];
+
+                if (bone == Bone.ClavicleL)
+                {
+                    /*
+                     * Versions of MM possibly serialized ClavicleL improperly.
+                     * At least I think that's what happened otherwise why would they make this check at all.
+                     * https://git.coder.horse/meidomustard/modifiedMM/src/master/MultipleMaids/CM3D2/MultipleMaids/Plugin/MultipleMaids.Update.cs#L4355 
+                     *
+                     * Just look at the way MM serializes rotations.
+                     * https://git.coder.horse/meidomustard/modifiedMM/src/master/MultipleMaids/CM3D2/MultipleMaids/Plugin/MultipleMaids.Update.cs#L2364
+                     * It is most definitely possible MM dev missed a component.
+                     *
+                     * Also why is strArray9.Length == 2 acceptable? If the length were only 2,
+                     * float.Parse(strArray9[2]) would throw an index out of range exception???
+                     */
+                    if (!reader.ReadBoolean())
+                    {
+                        reader.ReadQuaternion();
+                        continue;
+                    }
+                }
+
+                var rotation = reader.ReadQuaternion();
+
+                if (sixtyFourFlag || i > localRotationIndex)
+                    BoneTransform[bone].localRotation = rotation;
+                else
+                    BoneTransform[bone].rotation = rotation;
             }
+
             // WHY????
-            GameMain.Instance.StartCoroutine(ApplyHipPosition(binaryReader.ReadVector3()));
+            GameMain.Instance.StartCoroutine(ApplyHipPosition(reader.ReadVector3()));
         }
 
         /*

+ 13 - 2
src/MeidoPhotoStudio.Plugin/Serialization/Serializers/MeidoSerializer.cs

@@ -165,8 +165,19 @@ namespace MeidoPhotoStudio.Plugin
 
             _ = reader.ReadVersion();
 
-            body.quaDefEyeL = reader.ReadQuaternion() * meido.DefaultEyeRotL;
-            body.quaDefEyeR = reader.ReadQuaternion() * meido.DefaultEyeRotR;
+            var mmConverted = metadata.MMConverted;
+
+            var eyeRotationL = reader.ReadQuaternion();
+            var eyeRotationR = reader.ReadQuaternion();
+
+            if (!mmConverted)
+            {
+                eyeRotationL *= meido.DefaultEyeRotL;
+                eyeRotationR *= meido.DefaultEyeRotR;
+            }
+
+            body.quaDefEyeL = eyeRotationL;
+            body.quaDefEyeR = eyeRotationR;
 
             var freeLook = meido.FreeLook = reader.ReadBoolean();
             var offsetLookTarget = reader.ReadVector3();

+ 1 - 1
src/MeidoPhotoStudio.Plugin/Utility.cs

@@ -135,7 +135,7 @@ namespace MeidoPhotoStudio.Plugin
         public static string HandItemToOdogu(string menu)
         {
             menu = menu.Substring(menu.IndexOf('_') + 1);
-            menu = menu.Substring(0, menu.IndexOf("_i_.menu"));
+            menu = menu.Substring(0, menu.IndexOf("_i_.menu", StringComparison.OrdinalIgnoreCase));
             menu = $"odogu_{menu}";
             return menu;
         }