//DoWorkイベントハンドラ private void ProgressDialog_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker bw = (BackgroundWorker)sender; FileFormat.MQOFile mqo = new FileFormat.MQOFile(); int mc = pmx.Material.Count; int cw = 100 / mc; // 形状の変換 // pmxは材質ごとに面がある bw.ReportProgress(0, "材質と形状の変換中"); for (var i = 0; i < pmx.Material.Count; i++) { mqo.Material.Add(null); mqo.Object.Add(null); } Parallel.For(0, pmx.Material.Count, matID => { var pmxMat = pmx.Material[matID]; // 材質変換 var mqoMat = new FileFormat.MQOMaterial(pmxMat.Name); mqoMat.Color.R = (Decimal)pmxMat.Diffuse.R; mqoMat.Color.G = (Decimal)pmxMat.Diffuse.G; mqoMat.Color.B = (Decimal)pmxMat.Diffuse.B; mqoMat.Color.A = (Decimal)pmxMat.Diffuse.A; mqoMat.Diffuse = 1; mqoMat.Ambient = (Decimal)(pmxMat.Ambient.R + pmxMat.Ambient.G + pmxMat.Ambient.B)/3; mqoMat.Specular = (Decimal)(pmxMat.Specular.R + pmxMat.Specular.G + pmxMat.Specular.B)/3; mqoMat.Power = (Decimal)pmxMat.Power; if (pmxMat.Tex != null) mqoMat.Tex = pmxMat.Tex; mqo.Material[matID] = mqoMat; // 形状変換 var mqoObj = new FileFormat.MQOObject(pmxMat.Name); foreach (var face in pmxMat.Faces) { int v1 = appendVertex(mqoObj, face.Vertex1); int v2 = appendVertex(mqoObj, face.Vertex2); int v3 = appendVertex(mqoObj, face.Vertex3); int uv1 = appendUV(mqoObj, face.Vertex1); int uv2 = appendUV(mqoObj, face.Vertex2); int uv3 = appendUV(mqoObj, face.Vertex3); var mqoFace = new FileFormat.MQOFace(); mqoFace.MatID = matID; mqoFace.VertexID = new int[] { v1, v2, v3 }; mqoFace.UVID = new int[] { uv1, uv2, uv3 }; mqoObj.Face.Add(mqoFace); } mqo.Object[matID] = mqoObj; bw.ReportProgress(cw, 1); }); mqo.FixNames(); bw.ReportProgress(0, "書き出し中(バーは動きません (^-^;)"); // 書き出し mqo.WriteTo(mqopath); bw.ReportProgress(100, "書き出し完了"); //結果を設定する //e.Result = true; }
public void RegistToPmx(IPXPmx pmx, IPXPmxBuilder bld, FileFormat.MQOFile mqo, WorkVertexDict dict, BackgroundWorker bw) { int N = list.Length; for (int i = 0; i < N; i++) { bw.ReportProgress(100 * i / N, "面の登録中"); list[i].ForEach(f => { var xf = bld.Face(); xf.Vertex1 = dict.GetVertex(f.V0); xf.Vertex2 = dict.GetVertex(f.V1); xf.Vertex3 = dict.GetVertex(f.V2); pmx.Material[i].Faces.Add(xf); }); } }
public void RegistToPmx(IPXPmx pmx, IPXPmxBuilder bld, FileFormat.MQOFile mqo, BackgroundWorker bw) { int N = dict.Count; for (int i = 0; i < N; i++) { bw.ReportProgress(100 * i / N, "頂点の登録中"); var wv = dict[i]; IPXVertex v = bld.Vertex(); var mObj = mqo.Object[wv.ObjID]; var mv = mObj.Vertex[wv.VertID]; v.Position.X = (float)(mv.X); v.Position.Y = (float)(mv.Y); v.Position.Z = -(float)(mv.Z); FileFormat.MQOUV muv = mObj.UV[wv.UvID]; v.UV.U = (float)muv.U; v.UV.V = (float)muv.V; v.Normal.X = (float)mObj.Normal[wv.NormID].X; v.Normal.Y = (float)mObj.Normal[wv.NormID].Y; v.Normal.Z = -(float)mObj.Normal[wv.NormID].Z; wv.vertex = v; pmx.Vertex.Add(v); } }
//DoWorkイベントハンドラ private void ProgressDialog_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker bw = (BackgroundWorker)sender; FileFormat.MQOFile mqo = new FileFormat.MQOFile(); int mc = pmx.Material.Count; int cw = 100 / mc; // 形状の変換 // pmxは材質ごとに面がある bw.ReportProgress(0, "材質と形状の変換中"); for (var i = 0; i < pmx.Material.Count; i++) { mqo.Material.Add(null); mqo.Object.Add(null); } Parallel.For(0, pmx.Material.Count, matID => { var pmxMat = pmx.Material[matID]; // 材質変換 var mqoMat = new FileFormat.MQOMaterial(pmxMat.Name); mqoMat.Color.R = (Decimal)pmxMat.Diffuse.R; mqoMat.Color.G = (Decimal)pmxMat.Diffuse.G; mqoMat.Color.B = (Decimal)pmxMat.Diffuse.B; mqoMat.Color.A = (Decimal)pmxMat.Diffuse.A; mqoMat.Diffuse = 1; mqoMat.Ambient = (Decimal)(pmxMat.Ambient.R + pmxMat.Ambient.G + pmxMat.Ambient.B) / 3; mqoMat.Specular = (Decimal)(pmxMat.Specular.R + pmxMat.Specular.G + pmxMat.Specular.B) / 3; mqoMat.Power = (Decimal)pmxMat.Power; if (pmxMat.Tex != null) { mqoMat.Tex = pmxMat.Tex; } mqo.Material[matID] = mqoMat; // 形状変換 var mqoObj = new FileFormat.MQOObject(pmxMat.Name); foreach (var face in pmxMat.Faces) { int v1 = appendVertex(mqoObj, face.Vertex1); int v2 = appendVertex(mqoObj, face.Vertex2); int v3 = appendVertex(mqoObj, face.Vertex3); int uv1 = appendUV(mqoObj, face.Vertex1); int uv2 = appendUV(mqoObj, face.Vertex2); int uv3 = appendUV(mqoObj, face.Vertex3); var mqoFace = new FileFormat.MQOFace(); mqoFace.MatID = matID; mqoFace.VertexID = new int[] { v1, v2, v3 }; mqoFace.UVID = new int[] { uv1, uv2, uv3 }; mqoObj.Face.Add(mqoFace); } mqo.Object[matID] = mqoObj; bw.ReportProgress(cw, 1); }); mqo.FixNames(); bw.ReportProgress(0, "書き出し中(バーは動きません (^-^;)"); // 書き出し mqo.WriteTo(mqopath); bw.ReportProgress(100, "書き出し完了"); //結果を設定する //e.Result = true; }
//DoWorkイベントハンドラ private void ProgressDialog_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker bw = (BackgroundWorker)sender; bw.ReportProgress(0, "ファイル読み込み中(バーは動きません (^-^;)"); using (FileFormat.MQOFile mqo = FileFormat.MQOFile.load(mqopath, true)) // 三角面化して読み込む { if (mqo == null) { throw new Exception("読み込み失敗。おそらくmqoファイルの構文エラー。"); } if (mqo.Object.Count == 0) { throw new Exception("オブジェクトが空です。"); } // pmx作成 bld = PEStaticBuilder.Pmx; pmx = bld.Pmx(); pmx.Clear(); // モデル名は最初のオブジェクト名を利用する pmx.ModelInfo.ModelName = mqo.Object[0].Name; // 材質 int mc = mqo.Material.Count; if (mc == 0) { throw new Exception("材質がありません。少なくとも1つ材質が必要です。"); } int cw = 100 / mc; int pc = 0; mqo.Material.ForEach(m => { bw.ReportProgress(cw * pc++, "材質の変換中"); IPXMaterial pm = bld.Material(); pm.Name = m.Name; pm.Diffuse.R = (float)(m.Color.R * m.Diffuse); pm.Diffuse.G = (float)(m.Color.G * m.Diffuse); pm.Diffuse.B = (float)(m.Color.B * m.Diffuse); pm.Diffuse.A = (float)m.Color.A; pm.Ambient.R = (float)(m.Color.R * m.Ambient); pm.Ambient.G = (float)(m.Color.G * m.Ambient); pm.Ambient.B = (float)(m.Color.B * m.Ambient); pm.Specular.R = (float)(m.Color.R * m.Specular); pm.Specular.G = (float)(m.Color.G * m.Specular); pm.Specular.B = (float)(m.Color.B * m.Specular); pm.Power = (float)m.Power; pm.Tex = m.Tex; pmx.Material.Add(pm); }); // 各オブジェクトを処理 // ただし、非表示オブジェクトはスキップ mc = mqo.Object.Count; cw = 100 / mc; bw.ReportProgress(0, "法線を計算中"); Parallel.ForEach(mqo.Object, mObj => { if (mObj.Visible) { mObj.CalcNormals(); } bw.ReportProgress(cw, 1); }); // 先に頂点をすべて登録してから面を登録する // 頂点登録と面登録を交互に行うととんでもなく遅くなる mc = mqo.Material.Count; WorkFaceList workfacelist = new WorkFaceList(mc); WorkVertexDict workvertexdict = new WorkVertexDict(); mc = mqo.Object.Count; cw = 100 / mc; pc = 0; for (int objID = 0; objID < mc; objID++) { var mObj = mqo.Object[objID]; bw.ReportProgress(cw * pc++, String.Format("'{0}'の変換中", mObj.Name)); mObj.Face.ForEach(fc => { if (!mObj.Visible) { return; // 非表示オブジェクトは無視 } // 材質割り当てのない面は材質0として処理 int matID = fc.MatID < 0 ? 0 : fc.MatID; Func <int, int> get_vertex = i => workvertexdict.RegistVertex(objID, fc.VertexID[i], fc.UVID[i], fc.NormalID[i]); workfacelist.AddFace(matID, get_vertex(0), get_vertex(1), get_vertex(2)); }); } workvertexdict.RegistToPmx(pmx, bld, mqo, bw); workfacelist.RegistToPmx(pmx, bld, mqo, workvertexdict, bw); } }