Example #1
0
 public Quaternion MmdRotationToCustomRotation(Quaternion q, string cus_bone_name)
 {
     return
         (initPose.FindNodeByName(cus_bone_name).Rotation *
          pmd_initPose_diff_w.FindNodeByName(cus_bone_name).Rotation *
          q *
          pmd_initPose_diff.FindNodeByName(cus_bone_name).Rotation *
          Quaternion.Invert(pmd_initPose_diff_w.FindNodeByName(cus_bone_name).Rotation));
 }
Example #2
0
 private Matrix[] ClipBoneMatrices(TSOSubMesh sub_mesh, TMOFile tmo)
 {
     Matrix[] clipped_boneMatrices = new Matrix[sub_mesh.maxPalettes];
     for (int numPalettes = 0; numPalettes < sub_mesh.maxPalettes; numPalettes++)
     {
         TSONode tso_node = sub_mesh.GetBone(numPalettes);
         TMONode tmo_node = tmo.FindNodeByName(tso_node.Name);
         clipped_boneMatrices[numPalettes] = tso_node.OffsetMatrix * tmo_node.combined_matrix;
     }
     return(clipped_boneMatrices);
 }
Example #3
0
        private TMOFile InvertTmo(TMOFile tmo)
        {
            TMOFile output = tmo.Dup();

            foreach (TMONode node in tmo.nodes)
            {
                output.FindNodeByName(node.Name).Rotation
                    = Quaternion.Invert(node.Rotation);
            }

            return(output);
        }
Example #4
0
        private TMOFile MultiTmo(TMOFile tmo1, TMOFile tmo2)
        {
            TMOFile output = tmo1.Dup();

            foreach (TMONode node in tmo1.nodes)
            {
                output.FindNodeByName(node.Name).Rotation
                    = node.Rotation *
                      tmo2.FindNodeByName(node.Name).Rotation;
            }

            return(output);
        }
Example #5
0
        private TMOFile DiffWorldTmo(TMOFile tmo1, TMOFile tmo2)
        {
            TMOFile output = tmo1.Dup();

            foreach (TMONode node in tmo1.nodes)
            {
                output.FindNodeByName(node.Name).Rotation
                    = Quaternion.Invert(tmo2.FindNodeByName(node.Name).GetWorldRotation()) *
                      node.GetWorldRotation();
            }

            return(output);
        }
Example #6
0
        public void SaveVpd(TMOFile pose, string file_name)
        {
            TMOFile pose_diff = DiffTmo(pose, initPose);
            TMOFile output    =
                MultiTmo(
                    UnitaryTmo(pose_diff, pmd_initPose_diff_w),
                    InvertTmo(pmd_initPose_diff)
                    );
            TMOFile output2 = UnitaryTmo(pose_diff, pmd_initPose_diff_w);

            // ファイルを上書きし、Shift JISで書き込む
            System.IO.StreamWriter sw = new System.IO.StreamWriter(
                file_name,
                false,
                System.Text.Encoding.GetEncoding("shift_jis"));

            // ヘッダ
            sw.WriteLine(@"Vocaloid Pose Data file");
            sw.WriteLine(@"");
            sw.WriteLine(@"miku.osm;");
            sw.WriteLine((tmo2vpd.CorrespondBone.Count).ToString() + @";");

            // ボーンの回転
            int i = 0;

            foreach (KeyValuePair <string, List <string> > kvp in tmo2vpd.CorrespondBone)
            {
                sw.WriteLine(@"");
                sw.WriteLine(@"Bone" + i.ToString() + "{" + kvp.Key); i++;
                sw.WriteLine(@"0.000000,0.000000,0.000000;");

                Quaternion q;

                if (kvp.Key == "センター")
                {
                    q = output.FindNodeByName("W_Hips").Rotation *
                        output.FindNodeByName("W_Spine_Dummy").Rotation;
                }
                else if (kvp.Key == "下半身")
                {
                    q = Quaternion.Invert(output.FindNodeByName("W_Spine_Dummy").Rotation);
                }
                else if (kvp.Key == "頭")
                {
                    Quaternion face_q = output.FindNodeByName("face_oya").Rotation;

                    q = output.FindNodeByName("Head").Rotation *
                        new Quaternion(-face_q.X, face_q.Y, -face_q.Z, face_q.W);
                }
                else if (kvp.Key.IndexOf("捩") >= 0)
                {
                    q = Quaternion.Identity;

                    foreach (string bone_name in kvp.Value)
                    {
                        q = q * output2.FindNodeByName(bone_name).Rotation;
                    }
                }
                else
                {
                    q = Quaternion.Identity;

                    foreach (string bone_name in kvp.Value)
                    {
                        q = q * output.FindNodeByName(bone_name).Rotation;
                    }
                }

                sw.WriteLine(
                    (q.X * (-1)).ToString() + "," +
                    (q.Y * (-1)).ToString() + "," +
                    q.Z.ToString() + "," +
                    q.W.ToString() + ";");

                sw.WriteLine(@"}");
            }

            // ファイルを閉じる
            sw.Close();
        }
Example #7
0
        // MmdVmdMotionより、現時刻でのTmo情報を得る
        public void GetRotation(ref TMOFile tmo)
        {
            // -----------------------------------------------------
            // 表情の移植
            // -----------------------------------------------------

            foreach (MorphGroup mg in morph.Groups)
            {
                foreach (Morph mi in mg.Items)
                {
                    mi.Ratio = player.GetFaceRateByName(mi.Name);
                }
            }

            morph.Morph(tmo); // モーフ変形を実行


            // -----------------------------------------------------
            // ボーンのRotation情報を移植
            // -----------------------------------------------------

            PmdBone bone;

            // ミクとカス子ではセンターボーンが異なるので、調整が必要
            bone = pmd.getBoneByName("センター");
            Quaternion rot_center = tbr.MmdRotationToCustomRotation(
                new Quaternion(
                    (float)bone.m_vec4Rotate.x * (-1),
                    (float)bone.m_vec4Rotate.y * (-1),
                    (float)bone.m_vec4Rotate.z,
                    (float)bone.m_vec4Rotate.w
                    ),
                "W_Hips");

            bone = pmd.getBoneByName("下半身");
            Quaternion rot_down = tbr.MmdRotationToCustomRotation(
                new Quaternion(
                    (float)bone.m_vec4Rotate.x * (-1),
                    (float)bone.m_vec4Rotate.y * (-1),
                    (float)bone.m_vec4Rotate.z,
                    (float)bone.m_vec4Rotate.w
                    ),
                "W_Spine_Dummy");

            // センターの回転
            tmo.FindNodeByName("W_Hips").Rotation = rot_down * rot_center;

            // 下半身の回転
            tmo.FindNodeByName("W_Spine_Dummy").Rotation = Quaternion.Invert(rot_down);

            // センターの位置
            bone = pmd.getBoneByName("センター");
            Vector3 pos_center = new Vector3(
                bone.m_vec3Position.x,
                bone.m_vec3Position.y,
                -bone.m_vec3Position.z
                );
            Vector3 d = tmo.FindNodeByName("W_Spine1").GetWorldPosition()
                        - tmo.FindNodeByName("W_Hips").GetWorldPosition();

            tmo.FindNodeByName("W_Hips").Translation = pos_center + offset_position - d;

            // その他のボーンの回転
            foreach (KeyValuePair <string, string> kvp in girl2miku.boneCorrespond_v2t)
            {
                if (kvp.Key != "センター" && kvp.Key != "下半身")
                {
                    bone = pmd.getBoneByName(kvp.Key);

                    Quaternion q
                        = new Quaternion(
                              (float)bone.m_vec4Rotate.x * (-1),
                              (float)bone.m_vec4Rotate.y * (-1),
                              (float)bone.m_vec4Rotate.z,
                              (float)bone.m_vec4Rotate.w
                              );

                    tmo.FindNodeByName(kvp.Value).Rotation =
                        tbr.MmdRotationToCustomRotation(q, kvp.Value);
                }
            }
        }