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)); }
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); }
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); }
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); }
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); }
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(); }
// 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); } } }