public IMMDModelPart Create(int triangleCount, MMDVertexNm[] Vertices, Dictionary<string, object> OpaqueData) { IndexBuffer indexBuffer = null; if (OpaqueData.ContainsKey("IndexBuffer")) indexBuffer = OpaqueData["IndexBuffer"] as IndexBuffer; Vector2[] extVert = null; if (OpaqueData.ContainsKey("VerticesExtention")) extVert = OpaqueData["VerticesExtention"] as Vector2[]; if (indexBuffer == null) throw new ArgumentException("MMDModelPartXBoxFactoryのOpaqueDataには\"IndexBuffer\"キーとIndexBufferオブジェクトが必要です。", "OpaqueData"); if (extVert == null) throw new ArgumentException("MMDModelPartXboxFactoryのOpaqueDataには\"VerticesExtention\"キーが必要です。", "OpaqueData"); if (Vertices is MMDVertexNmTx[]) { if (Vertices is MMDVertexNmTxVc[]) return new MMDXBoxModelPartPNmTxVc(triangleCount, (MMDVertexNmTxVc[])Vertices, extVert, indexBuffer); else return new MMDXBoxModelPartPNmTx(triangleCount, (MMDVertexNmTx[])Vertices, extVert, indexBuffer); } else { if (Vertices is MMDVertexNmVc[]) return new MMDXBoxModelPartPNmVc(triangleCount, (MMDVertexNmVc[])Vertices, extVert, indexBuffer); else return new MMDXBoxModelPartPNm(triangleCount, (MMDVertexNm[])Vertices, extVert, indexBuffer); } }
/// <summary> /// 頂点変換 /// </summary> /// <param name="bones">頂点</param> /// <param name="vertin">MMD頂点データ</param> /// <param name="outPosition">頂点データ</param> /// <param name="outNormal">法線データ</param> public static void SkinVertex(Matrix[] bones, MMDVertexNm vertin, out Vector3 outPosition, out Vector3 outNormal) #endif { //影響ボーン取得 int b0 = vertin.BlendIndexX; int b1 = vertin.BlendIndexY; //ボーンマトリックスをブレンド Matrix skinnedTransformSum; Blend4x3Matrix(ref bones[b0], ref bones[b1], ref vertin.BlendWeights, out skinnedTransformSum); //ブレンドしたボーンによる変換を頂点に適応 Vector3.Transform(ref vertin.Position, ref skinnedTransformSum, out outPosition); Vector3.TransformNormal(ref vertin.Normal, ref skinnedTransformSum, out outNormal); }
/// <summary> /// コンストラクタ /// </summary> /// <param name="triangleCount">三角形の個数</param> /// <param name="vertices">頂点配列</param> /// <param name="vertMap">モデルの頂点とMMDの頂点対応</param> /// <param name="indexBuffer">インデックスバッファ</param> public MMDGPUModelPartPNm(int triangleCount, MMDVertexNm[] vertices, Dictionary<long, int[]> vertMap, IndexBuffer indexBuffer) : base(triangleCount, vertices.Length, vertMap, indexBuffer) { this.vertices = vertices; //GPUリソース作成 gpuVertices = new VertexPositionNormal[vertices.Length]; vertexBuffer = new WritableVertexBuffer(indexBuffer.GraphicsDevice, vertices.Length * 4, typeof(VertexPositionNormal)); //初期値代入 for (int i = 0; i < vertices.Length; i++) { gpuVertices[i].Position = vertices[i].Position; gpuVertices[i].Normal = vertices[i].Normal; } // put the vertices into our vertex buffer vertexOffset = vertexBuffer.SetData(gpuVertices); }
//ファクトリー関数 public IMMDModelPart Create(int triangleCount, MMDVertexNm[] Vertices, Dictionary<string, object> OpaqueData) { IndexBuffer indexBuffer = null; if (OpaqueData.ContainsKey("IndexBuffer")) indexBuffer = OpaqueData["IndexBuffer"] as IndexBuffer; Dictionary<long, int[]> VertMap = OpaqueData["VertMap"] as Dictionary<long, int[]>; if (indexBuffer == null) throw new ArgumentException("MMDModelPartGPUFactoryのOpaqueDataには\"IndexBuffer\"キーとIndexBufferオブジェクトが必要です。", "OpaqueData"); if (Vertices is MMDVertexNmTx[]) { if (Vertices is MMDVertexNmTxVc[]) return new MMDGPUModelPartPNmTxVc(triangleCount, (MMDVertexNmTxVc[])Vertices, VertMap, indexBuffer); else return new MMDGPUModelPartPNmTx(triangleCount, (MMDVertexNmTx[])Vertices, VertMap, indexBuffer); } else { if (Vertices is MMDVertexNmVc[]) return new MMDGPUModelPartPNmVc(triangleCount, (MMDVertexNmVc[])Vertices, VertMap, indexBuffer); else return new MMDGPUModelPartPNm(triangleCount, (MMDVertexNm[])Vertices, VertMap, indexBuffer); } }
/// <summary> /// 頂点変換 /// </summary> /// <param name="bones">頂点</param> /// <param name="vertin">MMD頂点データ</param> /// <param name="outPosition">頂点データ</param> /// <param name="outNormal">法線データ</param> public static void SkinVertex(Matrix[] bones, MMDVertexNm vertin, out Vector4 outPosition, out Vector3 outNormal)
public MMDModel Load(string filename, Dictionary<string, object> opaqueData) { //GraphicsDataのチェック if (!opaqueData.ContainsKey("GraphicsDevice")) throw new ArgumentException("opaqueデータに{\"GraphicsDevice\",GraphicsDevice}がありません", "opaqueData"); GraphicsDevice graphics = opaqueData["GraphicsDevice"] as GraphicsDevice; if (graphics == null) throw new ArgumentException("opaqueデータに\"GraphicsDevice\"のキーはありましたが、ValueにGraphicsDeviceが入っていません"); //PMDのロード MikuMikuDance.Model.MMDModel model = MikuMikuDance.Model.ModelManager.Read(filename); MikuMikuDance.Model.Ver1.MMDModel1 model1 = model as MikuMikuDance.Model.Ver1.MMDModel1; if (model1 == null) throw new System.IO.FileLoadException("ファイルのロードに失敗しました", filename); List<IMMDModelPart> parts = new List<IMMDModelPart>(); MMDBoneManager manager; Dictionary<string, MMDMotionData> attachedMotion = new Dictionary<string, MMDMotionData>(); long FaceIndex = 0; //ボーンマネージャの作成 MMDBone[] bones = new MMDBone[model1.Bones.Length]; for (int i = 0; i < bones.Length; ++i) { bones[i].BindPose } //マテリアルごとにモデルを作成 for (long i = 0; i < model1.Materials.LongLength; ++i) { List<ushort> vertIndices = new List<ushort>(); List<int> faceIndices = new List<int>(); Dictionary<ushort, int> vertMap = new Dictionary<ushort, int>(); //頂点インデックスの作成 for (long j = FaceIndex; j < FaceIndex + model1.Materials[i].FaceVertCount; ++j) { ushort VertIndex = model1.FaceVertexes[j]; int vpos; if (vertMap.TryGetValue(VertIndex, out vpos)) { faceIndices.Add(vpos); } else { vertMap.Add(VertIndex, vertIndices.Count); faceIndices.Add(vertIndices.Count); vertIndices.Add(VertIndex); } } //インデックスバッファの作成(GraphicsDeviceがいる。どうする?) IndexBuffer indexbuffer; //頂点の作成 MMDVertexNm[] verts; MMDVertexNmTx[] vertsTx = null; //頂点型判定と代入 if (!string.IsNullOrEmpty(model1.Materials[i].TextureFileName)) { vertsTx = new MMDVertexNmTx[vertIndices.Count]; verts = vertsTx; } else verts = new MMDVertexNm[vertIndices.Count]; for (int vi = 0; vi < verts.LongLength; ++vi) { MikuMikuDance.Model.Ver1.ModelVertex modelvert = model1.Vertexes[vertIndices[vi]]; verts[vi].Position = MMDXMath.ToVector3(modelvert.Pos); verts[vi].Normal = MMDXMath.ToVector3(modelvert.NormalVector); verts[vi].BlendWeights = new Microsoft.Xna.Framework.Vector2(modelvert.BoneWeight / 100f, 1.0f - modelvert.BoneWeight / 100f); verts[vi].BlendIndexX = modelvert.BoneNum[0]; verts[vi].BlendIndexY = modelvert.BoneNum[1]; if (verts[vi].BlendIndexX < 0 && verts[vi].BlendIndexX >= manager.Count) { verts[vi].BlendWeights.X = 0; verts[vi].BlendIndexX = 0; } if (verts[vi].BlendIndexY < 0 && verts[vi].BlendIndexY >= manager.Count) { verts[vi].BlendWeights.Y = 0; verts[vi].BlendIndexY = 0; } if (vertsTx != null) vertsTx[vi].TextureCoordinate = MMDXMath.ToVector2(modelvert.UV); } //不透明データを作成 Dictionary<string, object> opaqueData = new Dictionary<string, object>(); opaqueData.Add("IndexBuffer", indexbuffer); parts.Add(normalFactory.Create(faceIndices.Count / 3, verts, opaqueData)); } return new MMDModel(parts, manager, attachedMotion); }
/// <summary> /// コンストラクタ /// </summary> /// <param name="triangleCount">三角形の個数</param> /// <param name="vertices">頂点配列</param> /// <param name="indexBuffer">インデックスバッファ</param> public MMDCPUModelPartPNm(int triangleCount, MMDVertexNm[] vertices, int[] vertMap, IndexBuffer indexBuffer) : base(triangleCount, vertices.Length, vertMap, indexBuffer) { this.vertices = vertices; //GPUリソース作成 gpuVertices = new VertexPositionNormal[vertices.Length]; vertexBuffer = new DynamicVertexBuffer(indexBuffer.GraphicsDevice, typeof(VertexPositionNormal), vertices.Length, BufferUsage.WriteOnly); //初期値代入 for (int i = 0; i < vertices.Length; i++) { gpuVertices[i].Position = vertices[i].Position; gpuVertices[i].Normal = vertices[i].Normal; } // put the vertices into our vertex buffer vertexBuffer.SetData(gpuVertices, 0, vertexCount, SetDataOptions.Discard); }