/// <summary> /// bone行列を更新します。 /// </summary> protected void UpdateBoneMatrices(TMONode tmo_node, TMOFrame tmo_frame) { matrixStack.Push(); if (tmo_frame != null) { // TMO animation tmo_node.TransformationMatrix = tmo_frame.matrices[tmo_node.ID].m; } Matrix m = tmo_node.TransformationMatrix; bool is_chichi = re_chichi.IsMatch(tmo_node.Name); if (is_chichi) { if (slide_matrices.Flat()) { slide_matrices.TransformChichiFlat(tmo_node, ref m); } } else { slide_matrices.TransformFace(tmo_node, ref m); } matrixStack.MultiplyMatrixLocal(m); m = matrixStack.Top; if (is_chichi) { if (!slide_matrices.Flat()) { slide_matrices.ScaleChichi(ref m); } } else { slide_matrices.Scale(tmo_node, ref m); } tmo_node.combined_matrix = m; foreach (TMONode child_node in tmo_node.children) { UpdateBoneMatrices(child_node, tmo_frame); } matrixStack.Pop(); }
/// <summary> /// bone行列を更新します。 /// </summary> protected void UpdateBoneMatrices(TMONode tmo_node, TMOFrame tmo_frame) { matrixStack.Push(); if (tmo_frame != null) { // TMO animation tmo_node.TransformationMatrix = tmo_frame.matrices[tmo_node.ID].m; } Matrix m = tmo_node.TransformationMatrix; bool is_chichi = re_chichi.IsMatch(tmo_node.Name); if (is_chichi && slide_matrices.Flat()) { switch (tmo_node.Name) { case "Chichi_Right1": m *= slide_matrices.ChichiR1; break; case "Chichi_Right2": m *= slide_matrices.ChichiR2; break; case "Chichi_Right3": m *= slide_matrices.ChichiR3; break; case "Chichi_Right4": m *= slide_matrices.ChichiR4; break; case "Chichi_Right5": m *= slide_matrices.ChichiR5; break; case "Chichi_Right5_end": m *= slide_matrices.ChichiR5E; break; case "Chichi_Left1": m *= slide_matrices.ChichiL1; break; case "Chichi_Left2": m *= slide_matrices.ChichiL2; break; case "Chichi_Left3": m *= slide_matrices.ChichiL3; break; case "Chichi_Left4": m *= slide_matrices.ChichiL4; break; case "Chichi_Left5": m *= slide_matrices.ChichiL5; break; case "Chichi_Left5_End": m *= slide_matrices.ChichiL5E; break; } // translationを維持する必要があるため // translationに対してscalingを打ち消す演算を行う。 Vector3 scaling = slide_matrices.Chichi; m.M41 /= scaling.X; m.M42 /= scaling.Y; m.M43 /= scaling.Z; switch (tmo_node.Name) { case "Chichi_Right1": case "Chichi_Left1": m *= Matrix.Scaling(scaling); break; } } switch (tmo_node.Name) { case "face_oya": Scale1(ref m, slide_matrices.FaceOya); break; case "eyeline_sita_L": case "L_eyeline_oya_L": case "Me_Right_Futi": m *= slide_matrices.EyeR; break; case "eyeline_sita_R": case "R_eyeline_oya_R": case "Me_Left_Futi": m *= slide_matrices.EyeL; break; } matrixStack.MultiplyMatrixLocal(m); m = matrixStack.Top; // スライダによる体型変更 // translationを維持する必要があるため // このscalingはmatrixStackに適用しない。 switch (tmo_node.Name) { case "W_Spine_Dummy": Scale1(ref m, slide_matrices.SpineDummy); break; case "W_Spine1": case "W_Spine2": Scale1(ref m, slide_matrices.Spine1); break; case "W_LeftHips_Dummy": case "W_RightHips_Dummy": Scale1(ref m, slide_matrices.HipsDummy); break; case "W_LeftUpLeg": case "W_RightUpLeg": Scale1(ref m, slide_matrices.UpLeg); break; case "W_LeftUpLegRoll": case "W_RightUpLegRoll": case "W_LeftLeg": case "W_RightLeg": Scale1(ref m, slide_matrices.UpLegRoll); break; case "W_LeftLegRoll": case "W_RightLegRoll": case "W_LeftFoot": case "W_RightFoot": case "W_LeftToeBase": case "W_RightToeBase": Scale1(ref m, slide_matrices.LegRoll); break; case "W_LeftArm_Dummy": case "W_RightArm_Dummy": Scale1(ref m, slide_matrices.ArmDummy); break; case "W_LeftArm": case "W_RightArm": case "W_LeftArmRoll": case "W_RightArmRoll": case "W_LeftForeArm": case "W_RightForeArm": case "W_LeftForeArmRoll": case "W_RightForeArmRoll": Scale1(ref m, slide_matrices.Arm); break; } if (is_chichi && !slide_matrices.Flat()) { Scale1(ref m, slide_matrices.Chichi); } tmo_node.combined_matrix = m; foreach (TMONode child_node in tmo_node.children) { UpdateBoneMatrices(child_node, tmo_frame); } matrixStack.Pop(); }