/// <summary> /// SQTTransformを生成 /// </summary> /// <param name="scales">スケールベクトル</param> /// <param name="rotation">回転クォータニオン</param> /// <param name="translation">移動ベクトル</param> /// <param name="result">SQTTransform</param> public static void Create(ref Vector3 scales, ref Quaternion rotation, ref Vector3 translation, out SQTTransform result) { result = new SQTTransform() { Scales = scales, Rotation = rotation, Translation = translation }; }
/// <summary> /// SQTTransformの乗算 /// </summary> public static void Multiply(ref SQTTransform value1, ref SQTTransform value2, out SQTTransform result) { result = new SQTTransform(); // 平行移動の算出 // 拡大→回転 Vector3 temp = new Vector3(); Vector3 newTranslation; temp.X = value1.Translation.X * value2.Scales.X; temp.Y = value1.Translation.Y * value2.Scales.Y; temp.Z = value1.Translation.Z * value2.Scales.Z; Vector3.Transform(ref temp, ref value2.Rotation, out newTranslation); newTranslation.X += value2.Translation.X; newTranslation.Y += value2.Translation.Y; newTranslation.Z += value2.Translation.Z; // 回転部分の結合(回転と拡大は独立だったはず……) Quaternion.Multiply(ref value1.Rotation, ref value2.Rotation, out result.Rotation); //拡大部分の結合 result.Scales.X = value1.Scales.X * value2.Scales.X; result.Scales.Y = value1.Scales.Y * value2.Scales.Y; result.Scales.Z = value1.Scales.Z * value2.Scales.Z; result.Translation = newTranslation; }
/// <summary> /// SQTTransformの乗算 /// </summary> public static void Multiply(ref SQTTransform value1, ref SQTTransform value2, out SQTTransform result) { result = new SQTTransform(); // 平行移動の算出 // 拡大→回転 Vector3 temp = new Vector3(); Vector3 newTranslation; temp.X = value1.Translation.X * value2.Scales.X; temp.Y = value1.Translation.Y * value2.Scales.Y; temp.Z = value1.Translation.Z * value2.Scales.Z; Vector3.Transform(ref temp, ref value2.Rotation, out newTranslation); newTranslation.X += value2.Translation.X; newTranslation.Y += value2.Translation.Y; newTranslation.Z += value2.Translation.Z; // 回転部分の結合(回転と拡大は独立だったはず……) Quaternion.Multiply(ref value1.Rotation, ref value2.Rotation, out result.Rotation); //拡大部分の結合 result.Scales.X = value1.Scales.X * value2.Scales.X; result.Scales.Y = value1.Scales.Y * value2.Scales.Y; result.Scales.Z = value1.Scales.Z * value2.Scales.Z; result.Translation = newTranslation; }
/// <summary> /// コンストラクタ /// </summary> /// <param name="name">名前</param> /// <param name="bindPose">バインドポーズ</param> /// <param name="inverseBindPose">逆バインドポーズ</param> /// <param name="skeletonHierarchy">親ボーン番号</param> public MMDBone(string name, SQTTransform bindPose, Matrix inverseBindPose, int skeletonHierarchy) { Name = name; BindPose = bindPose; InverseBindPose = inverseBindPose; SkeletonHierarchy = skeletonHierarchy; LocalTransform = bindPose; GlobalTransform = Matrix.Identity; }
/// <summary> /// 補完 /// </summary> /// <param name="frame1">フレーム1</param> /// <param name="frame2">フレーム2</param> /// <param name="Progress">進行度合い</param> /// <param name="result">補完結果</param> public static void Lerp(MMDBoneKeyFrame frame1, MMDBoneKeyFrame frame2, decimal Progress, out SQTTransform result) { decimal ProgX, ProgY, ProgZ, ProgR; ProgX = (decimal)frame2.Curve[0].Evaluate((float)Progress); ProgY = (decimal)frame2.Curve[1].Evaluate((float)Progress); ProgZ = (decimal)frame2.Curve[2].Evaluate((float)Progress); ProgR = (decimal)frame2.Curve[3].Evaluate((float)Progress); decimal x, y, z; Quaternion q; Vector3 scales; x = MathHelper.Lerp(frame1.Location.X, frame2.Location.X, ProgX); y = MathHelper.Lerp(frame1.Location.Y, frame2.Location.Y, ProgY); z = MathHelper.Lerp(frame1.Location.Z, frame2.Location.Z, ProgZ); Quaternion.Slerp(ref frame1.Quatanion, ref frame2.Quatanion, ProgR, out q); //MMDはスケールのアニメーションを含まないので、スケールのベジェ曲線計算は行わない Vector3.Lerp(ref frame1.Scales, ref frame2.Scales, Progress, out scales); Vector3 t = new Vector3(x, y, z); SQTTransform.Create(ref scales, ref q, ref t, out result); }
/// <summary> /// このフレームのSQTトランスフォームを取得 /// </summary> /// <param name="result">SQLトランスフォーム</param> public void GetSQTTransform(out SQTTransform result) { SQTTransform.Create(ref Scales, ref Quatanion, ref Location, out result); }
/// <summary> /// 姿勢の線形補間 /// </summary> /// <param name="pose1">姿勢1</param> /// <param name="pose2">姿勢2</param> /// <param name="amount">補完係数(0-1)</param> /// <param name="result">線形補間された姿勢</param> /// <remarks>Quaternionは球状線形補間を使用</remarks> internal static void Lerp(ref SQTTransform pose1, ref SQTTransform pose2, float amount, out SQTTransform result) { Vector3.Lerp(ref pose1.Scales, ref pose2.Scales, amount, out result.Scales); Vector3.Lerp(ref pose1.Translation, ref pose2.Translation, amount, out result.Translation); Quaternion.Slerp(ref pose1.Rotation, ref pose2.Rotation, amount, out result.Rotation); }
/// <summary> /// SQTTransformを生成 /// </summary> /// <param name="scales">スケールベクトル</param> /// <param name="rotation">回転クォータニオン</param> /// <param name="translation">移動ベクトル</param> /// <param name="result">SQTTransform</param> public static void Create(ref Vector3 scales, ref Quaternion rotation, ref Vector3 translation, out SQTTransform result) { result = new SQTTransform() { Scales = scales, Rotation = rotation, Translation = translation }; }
/// <summary> /// 姿勢の線形補間 /// </summary> /// <param name="pose1">姿勢1</param> /// <param name="pose2">姿勢2</param> /// <param name="amount">補完係数(0-1)</param> /// <param name="result">線形補間された姿勢</param> /// <remarks>Quaternionは球状線形補間を使用</remarks> internal static void Lerp(ref SQTTransform pose1, ref SQTTransform pose2, float amount, out SQTTransform result) { Vector3.Lerp(ref pose1.Scales, ref pose2.Scales, amount, out result.Scales); Vector3.Lerp(ref pose1.Translation, ref pose2.Translation, amount, out result.Translation); Quaternion.Slerp(ref pose1.Rotation, ref pose2.Rotation, amount, out result.Rotation); }