public static MMDMotion2 bake(MMDMotion2 motion, MMDModel1 model) { //ボーン取得 MMDBoneManager boneManager = ModelConverter.BuildBoneManager(model); //ベイク前のモーションとベイク後のモーションを準備 MMDMotion beforeMotion = MotionConverter.Convert(motion); MMDMotion afterMotion = CreateAfterMotionPrototype(beforeMotion, boneManager); //アニメーションプレイヤーを作成 AnimationPlayer player = new AnimationPlayer(boneManager); player.SetMotion(beforeMotion); //ベイクしていく uint frameNo = 0; bool ExitFlag = false; while (!ExitFlag) { ExitFlag = !player.Update(); //ボーンのグローバル行列更新 boneManager.CalcGlobalTransform(); //IK更新 boneManager.CalcIK(); //ベイク boneManager.bake(frameNo, afterMotion); ++frameNo; } //元のMMDMotion2に直して返却 return(MotionConverter.Convert(afterMotion, motion.ModelName)); }
public static MMDMotion2 bake(MMDMotion2 motion, MMDModel1 model) { //ボーン取得 MMDBoneManager boneManager = ModelConverter.BuildBoneManager(model); //ベイク前のモーションとベイク後のモーションを準備 MMDMotion beforeMotion = MotionConverter.Convert(motion); MMDMotion afterMotion = CreateAfterMotionPrototype(beforeMotion, boneManager); //アニメーションプレイヤーを作成 AnimationPlayer player = new AnimationPlayer(boneManager); player.SetMotion(beforeMotion); //ベイクしていく uint frameNo = 0; bool ExitFlag = false; while (!ExitFlag) { ExitFlag = !player.Update(); //ボーンのグローバル行列更新 boneManager.CalcGlobalTransform(); //IK更新 boneManager.CalcIK(); //ベイク boneManager.bake(frameNo, afterMotion); ++frameNo; } //元のMMDMotion2に直して返却 return MotionConverter.Convert(afterMotion, motion.ModelName); }
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)); }