高速化に成功。TimeRularがバグってるので正確な時間分からないが、どうも2体分ぐらい出す余裕まで出来たっぽい
@@ -22,8 +22,8 @@ | ||
22 | 22 | |
23 | 23 | internal MMDModel Model { get; set; } |
24 | 24 | Dictionary<string, int> BoneDic; |
25 | - Quaternion[] skinRots = null;//GetSkinRotation用の配列保持用。XBoxのGC回避のため | |
26 | - Vector4[] skinTranses = null;//GetSkinTransration用の配列保持用。XBoxのGC回避のため | |
25 | + internal Quaternion[] skinRots = null;//GetSkinRotation用の配列保持用。XBoxのGC回避のため | |
26 | + internal Vector4[] skinTranses = null;//GetSkinTransration用の配列保持用。XBoxのGC回避のため | |
27 | 27 | List<int> underIKs = new List<int>(20);//SolveIKのデータ計算用。XBoxのGC回避のため |
28 | 28 | |
29 | 29 | internal MMDBoneManager CloneForBake() |
@@ -169,35 +169,18 @@ | ||
169 | 169 | /// </summary> |
170 | 170 | internal void UpdateSkinTransforms() |
171 | 171 | { |
172 | + if (skinRots == null || skinRots.Length != Count | |
173 | + || skinTranses == null || skinTranses.Length != Count) | |
174 | + Refresh(); | |
172 | 175 | for (int bone = 0; bone < Count; bone++) |
173 | 176 | { |
174 | 177 | QuatTransform xform = |
175 | 178 | this[bone].BoneData.InverseBindPose * this[bone].WorldTransform; |
176 | 179 | |
177 | - this[bone].SkinRotation = xform.Rotation; | |
178 | - this[bone].SkinTranslation = new Vector4(xform.Translation.X, xform.Translation.Y, xform.Translation.Z, this[bone].SkinTranslation.W); | |
180 | + skinRots[bone] = xform.Rotation; | |
181 | + skinTranses[bone] = new Vector4(xform.Translation.X, xform.Translation.Y, xform.Translation.Z, skinTranses[bone].W); | |
179 | 182 | } |
180 | 183 | } |
181 | - internal Quaternion[] GetSkinRotation() | |
182 | - { | |
183 | - if (skinRots == null || skinRots.Length != Count) | |
184 | - Refresh(); | |
185 | - for (int bone = 0; bone < Count; bone++) | |
186 | - { | |
187 | - skinRots[bone] = this[bone].SkinRotation; | |
188 | - } | |
189 | - return skinRots; | |
190 | - } | |
191 | - internal Vector4[] GetSkinTranslation() | |
192 | - { | |
193 | - if (skinTranses == null || skinTranses.Length != Count) | |
194 | - Refresh(); | |
195 | - for (int bone = 0; bone < Count; bone++) | |
196 | - { | |
197 | - skinTranses[bone] = this[bone].SkinTranslation; | |
198 | - } | |
199 | - return skinTranses; | |
200 | - } | |
201 | 184 | private void Refresh() |
202 | 185 | { |
203 | 186 | skinRots = new Quaternion[Count]; |
@@ -77,7 +77,7 @@ | ||
77 | 77 | FaceManager = new MMDFaceManager(this); |
78 | 78 | Player = new AnimationPlayer(this); |
79 | 79 | // 頂点テクスチャの生成 |
80 | - int width = BoneManager.GetSkinRotation().Length; | |
80 | + int width = BoneManager.skinRots.Length; | |
81 | 81 | int height = 1; |
82 | 82 | |
83 | 83 | rotationTexture = new FlipTexture2D(graphics, width, height, 1, |
@@ -85,7 +85,7 @@ | ||
85 | 85 | |
86 | 86 | translationTexture = new FlipTexture2D(graphics, width, height, 1, |
87 | 87 | TextureUsage.Linear, SurfaceFormat.Vector4); |
88 | - faceTexture = new FlipTexture2D(graphics, FaceManager.GetFaceTranslation().Length, height, 1, | |
88 | + faceTexture = new FlipTexture2D(graphics, FaceManager.FaceTranslations.Length, height, 1, | |
89 | 89 | TextureUsage.Linear, SurfaceFormat.Vector4); |
90 | 90 | |
91 | 91 | //エッジ描画用のバッファ作成 |
@@ -174,10 +174,15 @@ | ||
174 | 174 | } |
175 | 175 | #endif |
176 | 176 | BoneManager.Update(); |
177 | + if (mmdXNA.TimeRular != null && UseTimeRular) | |
178 | + { | |
179 | + mmdXNA.TimeRular.EndMark(1, "BoneManager"); | |
180 | + mmdXNA.TimeRular.BeginMark(1, "FaceManager", Color.Cyan); | |
181 | + } | |
177 | 182 | FaceManager.Update(); |
178 | 183 | #if TRACE |
179 | 184 | if (mmdXNA.TimeRular != null && UseTimeRular) |
180 | - mmdXNA.TimeRular.EndMark(1, "BoneManager"); | |
185 | + mmdXNA.TimeRular.EndMark(1, "FaceManager"); | |
181 | 186 | #endif |
182 | 187 | if (mmdXNA.UsePhysic) |
183 | 188 | physics.Update(); |
@@ -229,13 +234,19 @@ | ||
229 | 234 | |
230 | 235 | } |
231 | 236 | |
232 | - | |
237 | + /*public bool Break = false; | |
238 | + System.Diagnostics.Stopwatch debug = new System.Diagnostics.Stopwatch(); | |
239 | + double Start = 0;*/ | |
240 | + | |
233 | 241 | private void ModelDraw(GraphicsDevice graphics, string EffectTechniqueName) |
234 | 242 | { |
235 | -#if TRACE | |
236 | - if (mmdXNA.TimeRular != null && UseTimeRular) | |
237 | - mmdXNA.TimeRular.BeginMark(1, "ModelDraw-Prepare", Color.PaleGreen); | |
238 | -#endif | |
243 | + //prepare処理 2.8294ms | |
244 | + /*if (!debug.IsRunning) | |
245 | + debug.Start(); | |
246 | + if (Break) | |
247 | + { | |
248 | + Start = debug.Elapsed.TotalMilliseconds; | |
249 | + }*/ | |
239 | 250 | //ビューとプロジェクション取得 |
240 | 251 | Matrix view = mmdXNA.Camera.GetViewMatrix(); |
241 | 252 | Matrix projection = mmdXNA.Camera.GetProjectionMatrix(graphics); |
@@ -245,12 +256,11 @@ | ||
245 | 256 | faceTexture.Flip(); |
246 | 257 | |
247 | 258 | //スキンアニメーション用テクスチャ |
248 | - rotationTexture.Texture.SetData<Quaternion>(BoneManager.GetSkinRotation()); | |
249 | - translationTexture.Texture.SetData<Vector4>(BoneManager.GetSkinTranslation()); | |
259 | + rotationTexture.Texture.SetData<Quaternion>(BoneManager.skinRots); | |
260 | + translationTexture.Texture.SetData<Vector4>(BoneManager.skinTranses); | |
250 | 261 | //フェイステクスチャ |
251 | - //TODO: GetFaceTranslationがボトルネック。 | |
252 | - faceTexture.Texture.SetData<Vector4>(FaceManager.GetFaceTranslation()); | |
253 | - | |
262 | + faceTexture.Texture.SetData<Vector4>(FaceManager.FaceTranslations); | |
263 | + | |
254 | 264 | //ライティング設定の取得 |
255 | 265 | Vector3 LightVector, LightColor; |
256 | 266 | mmdXNA.LightManager.GetParameters(out LightVector, out LightColor); |
@@ -258,24 +268,24 @@ | ||
258 | 268 | CullMode mode = graphics.RenderState.CullMode; |
259 | 269 | graphics.RenderState.CullMode = CullMode.None; |
260 | 270 | |
261 | -#if TRACE | |
262 | - if (mmdXNA.TimeRular != null && UseTimeRular) | |
271 | + /*if (Break) | |
263 | 272 | { |
264 | - mmdXNA.TimeRular.EndMark(1, "ModelDraw-Prepare"); | |
265 | - mmdXNA.TimeRular.BeginMark(1, "ModelDraw-Core", Color.RosyBrown); | |
266 | - } | |
267 | -#endif | |
273 | + System.Diagnostics.Debug.WriteLine((debug.Elapsed.TotalMilliseconds - Start).ToString()); | |
274 | + Break = false; | |
275 | + }*/ | |
276 | + //2.8294ms | |
277 | + //modelDraw処理 4.4583ms | |
268 | 278 | foreach (ModelMesh mesh in ModelData.ModelData.Meshes) |
269 | 279 | { |
270 | 280 | #if TRACE |
271 | - if (mmdXNA.TimeRular != null && UseTimeRular) | |
272 | - mmdXNA.TimeRular.BeginMark(2, "ModelDraw-SetData", Color.RosyBrown);//メモ:この中の実行コードが時間くってる | |
281 | + /*if (mmdXNA.TimeRular != null && UseTimeRular) | |
282 | + mmdXNA.TimeRular.BeginMark(2, "ModelDraw-SetData", Color.RosyBrown);*///メモ:この中の実行コードが時間くってる | |
273 | 283 | #endif |
274 | 284 | foreach (Effect effect in mesh.Effects)//メモ:エフェクト17回ループで処理時間食ってる |
275 | 285 | { |
276 | 286 | //エフェクトルーチン。 |
277 | 287 | //テクニックセット |
278 | - effect.CurrentTechnique = effect.Techniques[EffectTechniqueName]; | |
288 | + //effect.CurrentTechnique = effect.Techniques[EffectTechniqueName]; | |
279 | 289 | //ライティングセット |
280 | 290 | effect.Parameters["AmbientLightColor"].SetValue(mmdXNA.LightManager.AmbientLight.ToVector3()); |
281 | 291 | effect.Parameters["DirLight0Direction"].SetValue(LightVector); |
@@ -298,34 +308,24 @@ | ||
298 | 308 | effect.Parameters["View"].SetValue(view); |
299 | 309 | effect.Parameters["Projection"].SetValue(projection); |
300 | 310 | } |
301 | -#if TRACE | |
302 | - if (mmdXNA.TimeRular != null && UseTimeRular) | |
303 | - { | |
304 | - mmdXNA.TimeRular.EndMark(2, "ModelDraw-SetData"); | |
305 | - mmdXNA.TimeRular.BeginMark(2, "ModelDraw-Draw", Color.RoyalBlue); | |
306 | - } | |
307 | -#endif | |
311 | + | |
308 | 312 | mesh.Draw(); |
309 | -#if TRACE | |
310 | - if (mmdXNA.TimeRular != null && UseTimeRular) | |
311 | - mmdXNA.TimeRular.EndMark(2, "ModelDraw-Draw"); | |
312 | -#endif | |
313 | + | |
313 | 314 | } |
314 | -#if TRACE | |
315 | - if (mmdXNA.TimeRular != null && UseTimeRular) | |
316 | - { | |
317 | - mmdXNA.TimeRular.EndMark(1, "ModelDraw-Core"); | |
318 | - mmdXNA.TimeRular.BeginMark(1, "ModelDraw-After", Color.OrangeRed); | |
319 | - } | |
320 | -#endif | |
315 | + //7.2877ms | |
316 | + //after 0.1025ms | |
317 | + | |
318 | + | |
321 | 319 | //CullModeの変更を戻す |
322 | 320 | graphics.RenderState.CullMode = mode; |
323 | - //アクセサリの描画 | |
321 | + //7.3902ms | |
322 | + | |
323 | + //アクセサリの描画 3.5308ms | |
324 | 324 | foreach (var acc in Accessories) |
325 | 325 | { |
326 | 326 | if (BoneManager.ContainsBone(acc.Value.BoneName)) |
327 | 327 | { |
328 | - Matrix baseMat = BoneManager.GetWorldQuatTransform(BoneManager.IndexOf(acc.Value.BoneName)).CreateMatrix(); | |
328 | + Matrix baseMat = World * BoneManager.GetWorldQuatTransform(BoneManager.IndexOf(acc.Value.BoneName)).CreateMatrix(); | |
329 | 329 | if (acc.Key.Enabled) |
330 | 330 | { |
331 | 331 | acc.Key.Draw(baseMat * acc.Value.Transform); |
@@ -332,11 +332,10 @@ | ||
332 | 332 | } |
333 | 333 | } |
334 | 334 | } |
335 | -#if TRACE | |
336 | - if (mmdXNA.TimeRular != null && UseTimeRular) | |
337 | - mmdXNA.TimeRular.EndMark(1, "ModelDraw-After"); | |
338 | -#endif | |
335 | + //10.921ms | |
336 | + | |
339 | 337 | |
338 | + | |
340 | 339 | } |
341 | 340 | |
342 | 341 | } |
@@ -22,7 +22,7 @@ | ||
22 | 22 | /// WorldTransform |
23 | 23 | /// </summary> |
24 | 24 | public QuatTransform WorldTransform { get; set; } |
25 | - /// <summary> | |
25 | + /*/// <summary> | |
26 | 26 | /// SkinRotation |
27 | 27 | /// </summary> |
28 | 28 | public Quaternion SkinRotation { get; set; } |
@@ -29,7 +29,7 @@ | ||
29 | 29 | /// <summary> |
30 | 30 | /// SkinTranslation |
31 | 31 | /// </summary> |
32 | - public Vector4 SkinTranslation { get; set; } | |
32 | + public Vector4 SkinTranslation { get; set; }*/ | |
33 | 33 | |
34 | 34 | internal MMDBone() { }//内部からのみ |
35 | 35 | } |
@@ -10,7 +10,7 @@ | ||
10 | 10 | public class MMDFaceManager |
11 | 11 | { |
12 | 12 | MMDModel model; |
13 | - Vector4[] FaceTranslations;//頂点番号ごとの移動量 | |
13 | + internal Vector4[] FaceTranslations;//頂点番号ごとの移動量 | |
14 | 14 | internal Dictionary<string, float> FaceRates;//適応中の表情リスト |
15 | 15 | Dictionary<string, int> FaceDictionary;//表情辞書 |
16 | 16 | int baseIndex; |
@@ -81,10 +81,7 @@ | ||
81 | 81 | } |
82 | 82 | } |
83 | 83 | } |
84 | - internal Vector4[] GetFaceTranslation() | |
85 | - { | |
86 | - return FaceTranslations; | |
87 | - } | |
84 | + | |
88 | 85 | |
89 | 86 | internal bool ContainsFace(string p) |
90 | 87 | { |
@@ -332,7 +332,6 @@ | ||
332 | 332 | result.Faces[Frame, i].FaceName = FaceList[i]; |
333 | 333 | } |
334 | 334 | } |
335 | - System.Diagnostics.Debug.WriteLine(index.ToString()); | |
336 | 335 | } |
337 | 336 | } |
338 | 337 | } |
@@ -43,6 +43,18 @@ | ||
43 | 43 | World = world; |
44 | 44 | UseTimeRular = true; |
45 | 45 | game.Components.Add(this); |
46 | + //アクセサリの初期設定 | |
47 | + foreach (ModelMesh mesh in ModelData.Meshes) | |
48 | + { | |
49 | + foreach (BasicEffect effect in mesh.Effects) | |
50 | + { | |
51 | + effect.LightingEnabled = true; | |
52 | + effect.DirectionalLight0.Enabled = true; | |
53 | + effect.DirectionalLight1.Enabled = false; | |
54 | + effect.DirectionalLight2.Enabled = false; | |
55 | + | |
56 | + } | |
57 | + } | |
46 | 58 | } |
47 | 59 | /// <summary> |
48 | 60 | /// アクセサリの描画(DrawableGameComponent用 |
@@ -61,13 +73,6 @@ | ||
61 | 73 | /// <param name="baseTransform">基準トランスフォーム</param> |
62 | 74 | internal void Draw(Matrix baseTransform) |
63 | 75 | { |
64 | -#if TRACE | |
65 | - if (mmd.TimeRular != null && UseTimeRular) | |
66 | - { | |
67 | - mmd.TimeRular.BeginMark(1, "AccessoryDraw", Color.Red); | |
68 | - mmd.TimeRular.BeginMark(2, "AccessoryDraw-Prepare", Color.Gray); | |
69 | - } | |
70 | -#endif | |
71 | 76 | //アクセサリ描画用に設定 |
72 | 77 | Game.GraphicsDevice.RenderState.AlphaBlendEnable = true; |
73 | 78 | Game.GraphicsDevice.RenderState.BlendFunction = BlendFunction.Add; |
@@ -80,33 +85,19 @@ | ||
80 | 85 | //モデルのCullModeを変更 |
81 | 86 | CullMode mode = Game.GraphicsDevice.RenderState.CullMode; |
82 | 87 | Game.GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace; |
83 | -#if TRACE | |
84 | - if (mmd.TimeRular != null && UseTimeRular) | |
85 | - { | |
86 | - mmd.TimeRular.EndMark(2, "AccessoryDraw-Prepare"); | |
87 | - mmd.TimeRular.BeginMark(2, "AccessoryDraw-Core", Color.Green); | |
88 | - } | |
89 | -#endif | |
90 | 88 | //アクセサリの描画 |
91 | 89 | foreach (ModelMesh mesh in ModelData.Meshes) |
92 | 90 | { |
93 | 91 | foreach (BasicEffect effect in mesh.Effects) |
94 | 92 | { |
95 | - effect.LightingEnabled = true; | |
96 | 93 | effect.AmbientLightColor = mmd.LightManager.AmbientLight.ToVector3(); |
97 | 94 | effect.DirectionalLight0.Direction = mmd.LightManager.KeyLight.Direction; |
98 | 95 | effect.DirectionalLight0.Direction.Normalize(); |
99 | 96 | effect.DirectionalLight0.DiffuseColor = mmd.LightManager.KeyLight.Color.ToVector3();//new Vector3(0.2f, 0.2f, 0.2f); |
100 | 97 | effect.DirectionalLight0.SpecularColor = mmd.LightManager.KeyLight.Color.ToVector3(); |
101 | - effect.DirectionalLight0.Enabled = true; | |
102 | - effect.DirectionalLight1.Enabled = false; | |
103 | - effect.DirectionalLight2.Enabled = false; | |
104 | - effect.PreferPerPixelLighting = true; | |
105 | - | |
106 | 98 | effect.World = baseTransform * World; |
107 | 99 | effect.View = mmd.Camera.GetViewMatrix(); |
108 | 100 | effect.Projection = mmd.Camera.GetProjectionMatrix(Game.GraphicsDevice); |
109 | - | |
110 | 101 | } |
111 | 102 | mesh.Draw(); |
112 | 103 | } |
@@ -115,14 +106,6 @@ | ||
115 | 106 | //CullModeの変更を戻す |
116 | 107 | Game.GraphicsDevice.RenderState.CullMode = mode; |
117 | 108 | |
118 | -#if TRACE | |
119 | - if (mmd.TimeRular != null && UseTimeRular) | |
120 | - { | |
121 | - mmd.TimeRular.EndMark(2, "AccessoryDraw-Core"); | |
122 | - mmd.TimeRular.EndMark(1, "AccessoryDraw"); | |
123 | - } | |
124 | -#endif | |
125 | - | |
126 | 109 | } |
127 | 110 | |
128 | 111 | } |
@@ -42,5 +42,12 @@ | ||
42 | 42 | v1.00の次 |
43 | 43 | -処理の高速化 |
44 | 44 | -ライティングをMMDに近づけた(スポットライトだけ未実装) |
45 | -- | |
45 | +-モーションのベイク機能実装 | |
46 | 46 | |
47 | + | |
48 | +MMDX周りの技術メモ | |
49 | +ひにけにXNAのTimeRularはXBoxで嘘をつくことがある。Draw内でBeginMarkを呼び出した際に発生。理由は不明 | |
50 | +XBoxのGCはマーク&スィープ方式のGC。その為、毎回ヒープオブジェクトをnewしていると、GCが大量発生し、まともに動かない。よって、ヒープオブジェクトのメモリ管理が必要(GCの意味なし) | |
51 | +XBoxのCPUはインテル製のように、シングルスレッドを自動的に割り振ったりとかはしてくれない。 | |
52 | +XBoxのCPUは6コア、うち4コア使用可能。性能は4コアフル稼働でCore2Duo2G程度しかない。ボトルネックはCPU | |
53 | +XBoxのGPUは計算速いので、なるべくGPUに計算させる。 |