• R/O
  • SSH
  • HTTPS

mmdx: Commit


Commit MetaInfo

Revision16 (tree)
Zeit2010-03-01 22:40:42
Autorwilfrem

Log Message

マルチスレッド化の準備

Ändern Zusammenfassung

Diff

--- trunk/MMDImporter/Motion/MMDMotionProcessor.cs (revision 15)
+++ trunk/MMDImporter/Motion/MMDMotionProcessor.cs (revision 16)
@@ -27,7 +27,6 @@
2727 result.BoneMotions = new MMDBoneMotion[input.Motions.LongLength];
2828 if (result.BoneMotions.LongLength > int.MaxValue)
2929 throw new InvalidContentException("ボーンモーション数が多すぎます。MikuMikuDanceXNAは32bit符号付き整数最大値までしかモーション数をサポートしていません");
30- float beforeTan=0;
3130 for (long i = 0; i < result.BoneMotions.LongLength; i++)
3231 {
3332 result.BoneMotions[i] = new MMDBoneMotion();
--- trunk/MikuMikuDanceXNA/Model/AnimationPlayer.cs (revision 15)
+++ trunk/MikuMikuDanceXNA/Model/AnimationPlayer.cs (revision 16)
@@ -4,6 +4,7 @@
44 using MikuMikuDance.XNA.Model.ModelData;
55 using MikuMikuDance.XNA.Motion;
66 using Microsoft.Xna.Framework.Graphics;
7+using System.Threading;
78
89 namespace MikuMikuDance.XNA.Model
910 {
@@ -12,6 +13,7 @@
1213 public MMDMotion motion;
1314 public decimal frame;
1415 public bool IsLoopPlay;
16+
1517 public void Step(decimal time)
1618 {
1719 frame += time;
@@ -22,6 +24,9 @@
2224 }
2325 public void SetLoopPlay(bool value) { IsLoopPlay = value; }
2426 public void Reset() { motion = null; frame = -1; IsLoopPlay = false; }
27+
28+
29+
2530 }
2631 /// <summary>
2732 /// モーションファイルからアニメーションを再生するアニメーションプレイヤー
@@ -35,6 +40,7 @@
3540 List<OneTrack> trackPool = new List<OneTrack>(MikuMikuDanceXNA.MotionTrackCap);//オブジェクトプール
3641
3742
43+
3844 /// <summary>
3945 /// 一秒あたりのフレーム数
4046 /// </summary>
@@ -55,92 +61,7 @@
5561 FramePerSecond = 30;//MMDは30フレーム/秒が標準
5662 }
5763
58-
5964 /// <summary>
60- /// アニメーションの更新
61- /// </summary>
62- /// <remarks>モデルのUpdateから呼ばれるので、ユーザーが呼ぶ必要はありません</remarks>
63- internal void Update(GameTime gameTime)
64- {
65- for (int i=0;i<mmdMotion.Count;i++)
66- {
67- //再生中かどうかチェック
68- if (mmdMotion[i].frame >= 0)
69- {
70- //現在の再生フレームを更新
71- mmdMotion[i].Step((decimal)gameTime.ElapsedGameTime.Ticks / 10000.0m * FramePerSecond / 1000.0m);
72- InnerUpdate(mmdMotion[i].motion, mmdMotion[i].frame);
73- if (mmdMotion[i].frame > mmdMotion[i].motion.MaxFrame)
74- {
75- if (mmdMotion[i].IsLoopPlay)
76- {
77- if (mmdMotion[i].motion.MaxFrame == 0)
78- mmdMotion[i].SetFrame(0);
79- else
80- mmdMotion[i].Step(-mmdMotion[i].motion.MaxFrame);
81- }
82- else
83- mmdMotion[i].SetFrame(-1);
84- }
85-
86- }
87- }
88- //こちらではボーンマネージャのUpdateは行わない
89- }
90-
91- private void InnerUpdate(MMDMotion motion, decimal NowFrame)
92- {
93-#if TRACE
94- if (mmdModel.mmdXNA.TimeRular != null && mmdModel.UseTimeRular)
95- mmdModel.mmdXNA.TimeRular.BeginMark(2, "Anime-MotionToBone-" + mmdModel.Name, Color.BlueViolet);
96-#endif
97- //モーションのボーンリストを取得
98- List<string> motionBones = motion.GetBoneList();
99- //リストにあるボーンの位置を順番に更新
100- foreach (var bone in motionBones)
101- {
102- if (mmdModel.BoneManager.ContainsBone(bone))
103- {//存在しないボーンへのモーションは無視……
104- QuatTransform move = motion.GetBoneTransform(bone, NowFrame);
105- //ボーン処理
106- mmdModel.BoneManager[bone].BoneTransform = move * mmdModel.BoneManager[bone].BoneData.BindPose;
107- }
108- }
109-#if TRACE
110- if (mmdModel.mmdXNA.TimeRular != null && mmdModel.UseTimeRular)
111- {
112- mmdModel.mmdXNA.TimeRular.EndMark(2, "Anime-MotionToBone-" + mmdModel.Name);
113- mmdModel.mmdXNA.TimeRular.BeginMark(2, "Anime-IKBone-" + mmdModel.Name, Color.Red);
114- }
115-#endif
116- mmdModel.BoneManager.UpdateWorldTransforms();
117- //IKボーンの処理
118- for (int i = 0; i < mmdModel.BoneManager.Count; i++)
119- {
120- if (mmdModel.BoneManager[i].BoneData.IK != null)
121- mmdModel.BoneManager.SolveIK(i, mmdModel.BoneManager[i].BoneTransform);
122- }
123-#if TRACE
124- if (mmdModel.mmdXNA.TimeRular != null && mmdModel.UseTimeRular)
125- {
126- mmdModel.mmdXNA.TimeRular.EndMark(2, "Anime-IKBone-" + mmdModel.Name);
127- mmdModel.mmdXNA.TimeRular.BeginMark(2, "Anime-Face-" + mmdModel.Name, Color.BlueViolet);
128- }
129-#endif
130- //フェイスモーションの処理
131- List<string> faces = motion.GetFaceList();
132- //リストにあるフェイスのデータを順番に処理
133- foreach(var face in faces)
134- {
135- mmdModel.FaceManager.SetFace(face, motion.GetFaceRate(face, NowFrame));
136- }
137-#if TRACE
138- if (mmdModel.mmdXNA.TimeRular != null && mmdModel.UseTimeRular)
139- mmdModel.mmdXNA.TimeRular.EndMark(2, "Anime-Face-" + mmdModel.Name);
140-#endif
141- }
142-
143- /// <summary>
14465 /// モーションをセット
14566 /// </summary>
14667 /// <param name="motion">セットするMMDモーションデータ</param>
@@ -154,13 +75,13 @@
15475 {
15576 trackPool[0].Reset();
15677 trackPool[0].motion = motion;
157- trackPool[0].frame = -1;
78+ trackPool[0].frame = -1;
15879 mmdMotion.Add(trackPool[0]);
15980 trackPool.RemoveAt(0);
16081 }
16182 if (SetStartPos)
16283 InnerUpdate(motion, 0m);
163-
84+
16485 return mmdMotion.Count - 1;
16586 }
16687 /// <summary>
@@ -237,5 +158,89 @@
237158 Stop(index);
238159 mmdMotion.RemoveAt(index);
239160 }
161+
162+ /// <summary>
163+ /// アニメーションの更新
164+ /// </summary>
165+ /// <remarks>モデルのUpdateから呼ばれるので、ユーザーが呼ぶ必要はありません</remarks>
166+ internal void Update(GameTime gameTime)
167+ {
168+ for (int i=0;i<mmdMotion.Count;i++)
169+ {
170+ //再生中かどうかチェック
171+ if (mmdMotion[i].frame >= 0)
172+ {
173+ //現在の再生フレームを更新
174+ mmdMotion[i].Step((decimal)gameTime.ElapsedGameTime.Ticks / 10000.0m * FramePerSecond / 1000.0m);
175+ InnerUpdate(mmdMotion[i].motion, mmdMotion[i].frame);
176+ if (mmdMotion[i].frame > mmdMotion[i].motion.MaxFrame)
177+ {
178+ if (mmdMotion[i].IsLoopPlay)
179+ {
180+ if (mmdMotion[i].motion.MaxFrame == 0)
181+ mmdMotion[i].SetFrame(0);
182+ else
183+ mmdMotion[i].Step(-mmdMotion[i].motion.MaxFrame);
184+ }
185+ else
186+ mmdMotion[i].SetFrame(-1);
187+ }
188+
189+ }
190+ }
191+ //こちらではボーンマネージャのUpdateは行わない
192+ }
193+
194+ private void InnerUpdate(MMDMotion motion, decimal NowFrame)
195+ {
196+#if TRACE
197+ if (mmdModel.mmdXNA.TimeRular != null && mmdModel.UseTimeRular)
198+ mmdModel.mmdXNA.TimeRular.BeginMark(2, "Anime-MotionToBone-" + mmdModel.Name, Color.BlueViolet);
199+#endif
200+ //モーションのボーンリストを取得
201+ List<string> motionBones = motion.GetBoneList();
202+ //リストにあるボーンの位置を順番に更新
203+ foreach (var bone in motionBones)
204+ {
205+ if (mmdModel.BoneManager.ContainsBone(bone))
206+ {//存在しないボーンへのモーションは無視……
207+ QuatTransform move = motion.GetBoneTransform(bone, NowFrame);
208+ //ボーン処理
209+ mmdModel.BoneManager[bone].BoneTransform = move * mmdModel.BoneManager[bone].BoneData.BindPose;
210+ }
211+ }
212+#if TRACE
213+ if (mmdModel.mmdXNA.TimeRular != null && mmdModel.UseTimeRular)
214+ {
215+ mmdModel.mmdXNA.TimeRular.EndMark(2, "Anime-MotionToBone-" + mmdModel.Name);
216+ mmdModel.mmdXNA.TimeRular.BeginMark(2, "Anime-IKBone-" + mmdModel.Name, Color.Red);
217+ }
218+#endif
219+ mmdModel.BoneManager.UpdateWorldTransforms();
220+ //IKボーンの処理
221+ for (int i = 0; i < mmdModel.BoneManager.Count; i++)
222+ {
223+ if (mmdModel.BoneManager[i].BoneData.IK != null)
224+ mmdModel.BoneManager.SolveIK(i, mmdModel.BoneManager[i].BoneTransform);
225+ }
226+#if TRACE
227+ if (mmdModel.mmdXNA.TimeRular != null && mmdModel.UseTimeRular)
228+ {
229+ mmdModel.mmdXNA.TimeRular.EndMark(2, "Anime-IKBone-" + mmdModel.Name);
230+ mmdModel.mmdXNA.TimeRular.BeginMark(2, "Anime-Face-" + mmdModel.Name, Color.BlueViolet);
231+ }
232+#endif
233+ //フェイスモーションの処理
234+ List<string> faces = motion.GetFaceList();
235+ //リストにあるフェイスのデータを順番に処理
236+ foreach(var face in faces)
237+ {
238+ mmdModel.FaceManager.SetFace(face, motion.GetFaceRate(face, NowFrame));
239+ }
240+#if TRACE
241+ if (mmdModel.mmdXNA.TimeRular != null && mmdModel.UseTimeRular)
242+ mmdModel.mmdXNA.TimeRular.EndMark(2, "Anime-Face-" + mmdModel.Name);
243+#endif
244+ }
240245 }
241246 }
--- trunk/MikuMikuDanceXNA/Win32API.cs (nonexistent)
+++ trunk/MikuMikuDanceXNA/Win32API.cs (revision 16)
@@ -0,0 +1,37 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Linq;
4+using System.Text;
5+#if WINDOWS
6+using System.Runtime.InteropServices;
7+#endif
8+
9+namespace MikuMikuDance.XNA
10+{
11+#if WINDOWS
12+ /// <summary>
13+ /// Win32API用のクラス。Windows用
14+ /// </summary>
15+ internal static class Win32API
16+ {
17+ [DllImport("kernel32")]
18+ internal static extern void GetSystemInfo(ref SYSTEM_INFO ptmpsi);
19+
20+ [StructLayout(LayoutKind.Sequential)]
21+ public struct SYSTEM_INFO
22+ {
23+ public uint dwOemId;
24+ public uint dwPageSize;
25+ public uint lpMinimumApplicationAddress;
26+ public uint lpMaximumApplicationAddress;
27+ public uint dwActiveProcessorMask;
28+ public uint dwNumberOfProcessors;
29+ public uint dwProcessorType;
30+ public uint dwAllocationGranularity;
31+ public uint dwProcessorLevel;
32+ public uint dwProcessorRevision;
33+ }
34+
35+ }
36+#endif
37+}
--- trunk/MikuMikuDanceXNA/MikuMikuDanceXNA.cs (revision 15)
+++ trunk/MikuMikuDanceXNA/MikuMikuDanceXNA.cs (revision 16)
@@ -20,6 +20,11 @@
2020
2121 internal const int MotionTrackCap = 6;//モーショントラックのデータ確保数
2222
23+#if XBox//スレッド用の定数を用意したが、XBoxのGC回避のために使えない……
24+ internal const int NumThread = 4;//使用するスレッド数
25+#else
26+ internal readonly int NumThread;
27+#endif
2328 //properties...
2429 /// <summary>
2530 /// MikuMikuDance for XNAで用いるコンテンツマネージャ
@@ -43,6 +48,9 @@
4348 //デバッグ用
4449 //internal XnaDebugDraw debugDrawer;
4550 #if TRACE
51+ /// <summary>
52+ /// デバッグ用のタイム計測オブジェクト格納場所
53+ /// </summary>
4654 public ITimeRular TimeRular = null;
4755 #endif
4856
@@ -58,6 +66,13 @@
5866 {
5967 Content = game.Content;
6068 Camera = new MMDCamera();
69+#if WINDOWS
70+ //論理コア数を取得して、最適スレッド数を取得
71+ Win32API.SYSTEM_INFO info = new Win32API.SYSTEM_INFO();
72+ Win32API.GetSystemInfo(ref info);
73+ NumThread = (int)info.dwNumberOfProcessors;
74+#endif
75+ //物理エンジン実装中断
6176 /*Physic = CreatePhysicSystem();
6277 debugDrawer = new XnaDebugDraw(game);
6378 debugDrawer.Initialize();
--- trunk/MikuMikuDanceXNA/Motion/MotionData/MMDBoneMotion.cs (revision 15)
+++ trunk/MikuMikuDanceXNA/Motion/MotionData/MMDBoneMotion.cs (revision 16)
@@ -8,9 +8,20 @@
88 /// </summary>
99 public class BezierCurve
1010 {
11- public float Epsilon = 1.0e-3f;
11+ internal const float Epsilon = 1.0e-3f;
12+ /// <summary>
13+ /// ベジェ曲線に用いる点1
14+ /// </summary>
1215 public Vector2 v1 { get; set; }
16+ /// <summary>
17+ /// ベジェ曲線に用いる点2
18+ /// </summary>
1319 public Vector2 v2 { get; set; }
20+ /// <summary>
21+ /// 進行度合から移行度合を取得
22+ /// </summary>
23+ /// <param name="Progress">進行度合</param>
24+ /// <returns>移行度合</returns>
1425 public float Evaluate(float Progress)
1526 {
1627 //ニュートン法による近似
Show on old repository browser