/// <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; }
public static MMDBoneManager BuildBoneManager(MikuMikuDance.Model.Ver1.MMDModel1 model) { List <MMDBone> bones; List <MMDIK> iks; bones = new List <MMDBone>(); iks = new List <MMDIK>(); Matrix[] absPoses = new Matrix[model.Bones.LongLength]; //各ボーンの絶対座標を計算 for (long i = 0; i < model.Bones.LongLength; ++i) { Matrix.CreateTranslation((decimal)model.Bones[i].BoneHeadPos[0], (decimal)model.Bones[i].BoneHeadPos[1], (decimal)model.Bones[i].BoneHeadPos[2], out absPoses[i]); } for (long i = 0; i < model.Bones.LongLength; ++i) { Matrix localMatrix; if (model.Bones[i].ParentBoneIndex != 0xffff) { Matrix parentInv; Matrix.Invert(ref absPoses[model.Bones[i].ParentBoneIndex], out parentInv); Matrix.Multiply(ref parentInv, ref absPoses[i], out localMatrix); } else { localMatrix = absPoses[i]; } SQTTransform bindPose = SQTTransform.FromMatrix(localMatrix); Matrix inverseBindPose; Matrix.Invert(ref absPoses[i], out inverseBindPose); bones.Add(new MMDBone(model.Bones[i].BoneName, bindPose, inverseBindPose, model.Bones[i].ParentBoneIndex)); } for (long i = 0; i < model.IKs.LongLength; ++i) { List <int> ikChildBones = new List <int>(); foreach (var ikc in model.IKs[i].IKChildBoneIndex) { ikChildBones.Add(ikc); } iks.Add(new MMDIK(model.IKs[i].IKBoneIndex, model.IKs[i].IKTargetBoneIndex, model.IKs[i].Iterations, model.IKs[i].AngleLimit, ikChildBones)); } //ボーンインデックス→ボーンオブジェクト化 IKSetup(iks, bones); return(new MMDBoneManager(bones, iks)); }
public bool Update() { resultPoses.Clear(); bool result = motionTrack.Update(); foreach (KeyValuePair <string, SQTTransform> subpose in motionTrack.SubPoses) { resultPoses[subpose.Key] = subpose.Value; SQTTransform bindPose, sub = subpose.Value, local; if (BindPoses.TryGetValue(subpose.Key, out bindPose)) { SQTTransform.Multiply(ref sub, ref bindPose, out local); boneManager[subpose.Key].LocalTransform = local; } } return(result); }
/// <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); }