/// <summary> /// SQTTransformの乗算 /// </summary> public static void Multiply(ref SQTTransform value1, ref SQTTransform value2, out SQTTransform result) { result = new SQTTransform(); // 平行移動の算出 // 拡大→回転 Vector3 temp = new Vector3(); #if SlimDX Vector4 newTranslation; #else Vector3 newTranslation; #endif 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; #if SlimDX result.Translation = new Vector3(newTranslation.X, newTranslation.Y, newTranslation.Z); #else result.Translation = newTranslation; #endif }
/// <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; IsPhysics = false; }
/// <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, float Progress, out SQTTransform result) { float ProgX, ProgY, ProgZ,ProgR; ProgX = frame2.Curve[0].Evaluate(Progress); ProgY = frame2.Curve[1].Evaluate(Progress); ProgZ = frame2.Curve[2].Evaluate(Progress); ProgR = frame2.Curve[3].Evaluate(Progress); float 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> /// 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); }