internal static Dictionary<string, List<MMDBoneKeyFrame>> SplitBoneMotion(MMDBoneKeyFrame[] keyframes) { Dictionary<string, List<MMDBoneKeyFrame>> result = new Dictionary<string, List<MMDBoneKeyFrame>>(); foreach (var keyframe in keyframes) { if (!result.ContainsKey(keyframe.BoneName)) result.Add(keyframe.BoneName, new List<MMDBoneKeyFrame>()); result[keyframe.BoneName].Add(keyframe); } foreach (var boneframes in result) { boneframes.Value.Sort((x, y) => (int)((long)x.FrameNo - (long)y.FrameNo)); } 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, 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); }
public MMDMotion Load(string filename, float scale) { filename = Path.GetFullPath(filename); MikuMikuDance.Motion.Motion2.MMDMotion2 input; input = MotionManager.Read(filename, CoordinateType.RightHandedCoordinate, scale) as MikuMikuDance.Motion.Motion2.MMDMotion2; if (input == null) return null; MMDMotion result = new MMDMotion(); //ボーンモーションデータの変換 MMDBoneKeyFrame[] BoneFrames = new MMDBoneKeyFrame[input.Motions.LongLength]; for (long i = 0; i < input.Motions.LongLength; i++) { BoneFrames[i] = new MMDBoneKeyFrame(); BoneFrames[i].BoneName = input.Motions[i].BoneName; BoneFrames[i].FrameNo = input.Motions[i].FrameNo; BoneFrames[i].Curve = new BezierCurve[4]; for (int j = 0; j < BoneFrames[i].Curve.Length; j++) { BezierCurve curve = new BezierCurve(); curve.v1 = new Vector2((float)input.Motions[i].Interpolation[0][0][j] / 128f, (float)input.Motions[i].Interpolation[0][1][j] / 128f); curve.v2 = new Vector2((float)input.Motions[i].Interpolation[0][2][j] / 128f, (float)input.Motions[i].Interpolation[0][3][j] / 128f); BoneFrames[i].Curve[j] = curve; } BoneFrames[i].Scales = new Vector3(1, 1, 1); BoneFrames[i].Location = new Vector3(input.Motions[i].Location[0], input.Motions[i].Location[1], input.Motions[i].Location[2]); BoneFrames[i].Quatanion = new Quaternion(input.Motions[i].Quatanion[0], input.Motions[i].Quatanion[1], input.Motions[i].Quatanion[2], input.Motions[i].Quatanion[3]); BoneFrames[i].Quatanion.Normalize(); } result.BoneFrames = MotionHelper.SplitBoneMotion(BoneFrames); //表情モーションの変換 MMDFaceKeyFrame[] FaceFrames = new MMDFaceKeyFrame[input.FaceMotions.LongLength]; for (long i = 0; i < input.FaceMotions.Length; i++) { FaceFrames[i] = new MMDFaceKeyFrame(); FaceFrames[i].Rate = input.FaceMotions[i].Rate; FaceFrames[i].FaceName = input.FaceMotions[i].FaceName; FaceFrames[i].FrameNo = input.FaceMotions[i].FrameNo; float temp = input.FaceMotions[i].FrameNo; } result.FaceFrames = MotionHelper.SplitFaceMotion(FaceFrames); //カメラモーションの変換 MMDCameraKeyFrame[] CameraFrames = new MMDCameraKeyFrame[input.CameraMotions.LongLength]; for (long i = 0; i < input.CameraMotions.Length; i++) { CameraFrames[i] = new MMDCameraKeyFrame(); CameraFrames[i].FrameNo = input.CameraMotions[i].FrameNo; CameraFrames[i].Length = input.CameraMotions[i].Length; CameraFrames[i].Location = MMDXMath.ToVector3(input.CameraMotions[i].Location); CameraFrames[i].Quatanion = MMDXMath.CreateQuaternionFromYawPitchRoll(input.CameraMotions[i].Rotate[1], input.CameraMotions[i].Rotate[0], input.CameraMotions[i].Rotate[2]); CameraFrames[i].ViewAngle = MathHelper.ToRadians(input.CameraMotions[i].ViewingAngle); CameraFrames[i].Curve = new BezierCurve[6]; for (int j = 0; j < CameraFrames[i].Curve.Length; j++) { BezierCurve curve = new BezierCurve(); curve.v1 = new Vector2((float)input.CameraMotions[i].Interpolation[j][0] / 128f, (float)input.CameraMotions[i].Interpolation[j][2] / 128f); curve.v2 = new Vector2((float)input.CameraMotions[i].Interpolation[j][1] / 128f, (float)input.CameraMotions[i].Interpolation[j][3] / 128f); CameraFrames[i].Curve[j] = curve; } } result.CameraFrames = new List<MMDCameraKeyFrame>(CameraFrames); //ライトモーションの変換 MMDLightKeyFrame[] LightFrames = new MMDLightKeyFrame[input.LightMotions.LongLength]; for (long i = 0; i < input.LightMotions.Length; i++) { LightFrames[i] = new MMDLightKeyFrame(); LightFrames[i].FrameNo = input.LightMotions[i].FrameNo; LightFrames[i].Color = MMDXMath.ToVector3(input.LightMotions[i].Color); LightFrames[i].Location = MMDXMath.ToVector3(input.LightMotions[i].Location); } result.LightFrames = new List<MMDLightKeyFrame>(LightFrames); //変換したデータを返却 return result; }