public static void Write(BinaryWriter bw, TSOSubMesh item) { bw.Write(item.spec); bw.Write(item.numbones); foreach (int k in item.bones) { bw.Write(k); } bw.Write(item.numvertices); foreach (Vertex k in item.vertices) { Write(bw, k); } }
protected override bool DoGenerateMeshes() { meshes = new List <TSOMesh>(); foreach (MqoObject obj in mqo.Objects) { if (obj.name.ToLower() == "bone") { continue; } Console.WriteLine("object:" + obj.name); // 一番近い頂点への参照 List <int> vref = new List <int>(obj.vertices.Count); foreach (UVertex i in obj.vertices) { vref.Add(pc.NearestIndex(i.Pos.x, i.Pos.y, i.Pos.z)); } obj.CreateNormal(); List <int> faces_1 = new List <int>(); List <int> faces_2 = new List <int>(); Heap <int> bh = new Heap <int>(); Heap <Vertex> vh = new Heap <Vertex>(); Vertex[] refvs = new Vertex[3]; List <ushort> vert_indices = new List <ushort>(); Dictionary <int, bool> adding_bone_indices = new Dictionary <int, bool>(); List <TSOSubMesh> subs = new List <TSOSubMesh>(); for (int i = 0, n = obj.faces.Count; i < n; ++i) { faces_1.Add(i); } #region ボーンパーティション Console.WriteLine(" vertices bone_indices"); Console.WriteLine(" -------- ------------"); while (faces_1.Count != 0) { int spec = obj.faces[faces_1[0]].spec; bh.Clear(); vh.Clear(); vert_indices.Clear(); foreach (int f in faces_1) { MqoFace face = obj.faces[f]; if (face.spec != spec) { faces_2.Add(f); continue; } for (int k = 0; k < 3; ++k) { refvs[k] = refverts[vref[face.vert_indices[k]]]; } adding_bone_indices.Clear(); for (int k = 0; k < 3; ++k) { UInt32 idx0 = refvs[k].Idx; Point4 wgt0 = refvs[k].Wgt; byte * idx = (byte *)(&idx0); float *wgt = (float *)(&wgt0); for (int l = 0; l < 4; ++l) { if (wgt[l] <= float.Epsilon) { continue; } if (bh.map.ContainsKey(idx[l])) { continue; } adding_bone_indices[idx[l]] = true; } } if (bh.Count + adding_bone_indices.Count > 16) { faces_2.Add(f); continue; } foreach (int i in adding_bone_indices.Keys) { bh.Add(i); } for (int k = 0; k < 3; ++k) { UInt32 idx0 = refvs[k].Idx; Point4 wgt0 = refvs[k].Wgt; byte * idx = (byte *)(&idx0); float *wgt = (float *)(&wgt0); for (int l = 0; l < 4; ++l) { if (wgt[l] <= float.Epsilon) { continue; } idx[l] = (byte)bh[idx[l]]; } refvs[k].Idx = idx0; } Vertex va = new Vertex(obj.vertices[face.a].Pos, refvs[0].Wgt, refvs[0].Idx, obj.vertices[face.a].Nrm, new Point2(face.ta.x, 1 - face.ta.y)); Vertex vb = new Vertex(obj.vertices[face.b].Pos, refvs[1].Wgt, refvs[1].Idx, obj.vertices[face.b].Nrm, new Point2(face.tb.x, 1 - face.tb.y)); Vertex vc = new Vertex(obj.vertices[face.c].Pos, refvs[2].Wgt, refvs[2].Idx, obj.vertices[face.c].Nrm, new Point2(face.tc.x, 1 - face.tc.y)); vert_indices.Add(vh.Add(va)); vert_indices.Add(vh.Add(vc)); vert_indices.Add(vh.Add(vb)); } ushort[] optimized_indices = NvTriStrip.Optimize(vert_indices.ToArray()); TSOSubMesh sub = new TSOSubMesh(); sub.spec = spec; sub.numbones = bh.Count; sub.bones = bh.ary.ToArray(); sub.numvertices = optimized_indices.Length; Vertex[] vertices = new Vertex[optimized_indices.Length]; for (int i = 0; i < optimized_indices.Length; ++i) { vertices[i] = vh.ary[optimized_indices[i]]; } sub.vertices = vertices; Console.WriteLine(" {0,8} {1,12}", sub.vertices.Length, sub.bones.Length); subs.Add(sub); List <int> faces_tmp = faces_1; faces_1 = faces_2; faces_2 = faces_tmp; faces_tmp.Clear(); } #endregion TSOMesh mesh = new TSOMesh(); mesh.name = obj.name; mesh.numsubs = subs.Count; mesh.sub_meshes = subs.ToArray(); mesh.matrix = Matrix44.Identity; mesh.effect = 0; meshes.Add(mesh); } return(true); }
protected override bool DoGenerateMeshes() { meshes = new List <TSOMesh>(); foreach (MqoObject i in mqo.Objects) { if (i.name.ToLower() == "bone") { continue; } Console.WriteLine("object:" + i.name); // 一番近い頂点への参照 List <int> vref = new List <int>(i.vertices.Count); foreach (Point3 j in i.vertices) { vref.Add(pc.NearestIndex(j.x, j.y, j.z)); } // 法線生成 Point3[] nrm = new Point3[i.vertices.Count]; foreach (MqoFace j in i.faces) { Point3 v1 = Point3.Normalize(i.vertices[j.b] - i.vertices[j.a]); Point3 v2 = Point3.Normalize(i.vertices[j.c] - i.vertices[j.b]); Point3 n = Point3.Normalize(Point3.Cross(v1, v2)); nrm[j.a] -= n; nrm[j.b] -= n; nrm[j.c] -= n; } for (int j = 0; j < nrm.Length; ++j) { nrm[j] = Point3.Normalize(nrm[j]); } // フェイスの組成 List <int> faces1 = new List <int>(); List <int> faces2 = new List <int>(); //int[] bonecnv = new int[tsor.nodes.Length]; // ボーン変換テーブル VertexHeap <Vertex> vh = new VertexHeap <Vertex>(); Vertex[] v = new Vertex[3]; List <int> bones = new List <int>(16); List <ushort> indices = new List <ushort>(); Dictionary <int, int> selected = new Dictionary <int, int>(); Dictionary <int, int> work = new Dictionary <int, int>(); List <TSOSubMesh> subs = new List <TSOSubMesh>(); for (int j = 0, n = i.faces.Count; j < n; ++j) { faces1.Add(j); } #region ボーンパーティション Console.WriteLine(" vertices bone_indices"); Console.WriteLine(" -------- ------------"); while (faces1.Count > 0) { int mtl = i.faces[faces1[0]].mtl; selected.Clear(); indices.Clear(); vh.Clear(); bones.Clear(); foreach (int j in faces1) { MqoFace f = i.faces[j]; if (f.mtl != mtl) { faces2.Add(j); continue; } v[0] = vlst[vref[f.a]]; v[1] = vlst[vref[f.b]]; v[2] = vlst[vref[f.c]]; work.Clear(); for (int k = 0; k < 3; ++k) { Vertex vv = v[k]; UInt32 idx0 = vv.Idx; Point4 wgt0 = vv.Wgt; byte * idx = (byte *)(&idx0); float *wgt = (float *)(&wgt0); for (int l = 0; l < 4; ++l) { if (wgt[l] <= float.Epsilon) { continue; } if (selected.ContainsKey(idx[l])) { continue; } if (!work.ContainsKey(idx[l])) { work.Add(idx[l], 0); } } } if (selected.Count + work.Count > 16) { faces2.Add(j); continue; } // ボーンリストに足してvalid foreach (KeyValuePair <int, int> l in work) { selected.Add(l.Key, selected.Count); // ボーンテーブルに追加 bones.Add(l.Key); } // \todo 点の追加 Vertex va = new Vertex(i.vertices[f.a], v[0].Wgt, v[0].Idx, nrm[f.a], new Point2(f.ta.x, 1 - f.ta.y)); Vertex vb = new Vertex(i.vertices[f.b], v[1].Wgt, v[1].Idx, nrm[f.b], new Point2(f.tb.x, 1 - f.tb.y)); Vertex vc = new Vertex(i.vertices[f.c], v[2].Wgt, v[2].Idx, nrm[f.c], new Point2(f.tc.x, 1 - f.tc.y)); indices.Add(vh.Add(va)); indices.Add(vh.Add(vc)); indices.Add(vh.Add(vb)); } // フェイス最適化 ushort[] nidx = NvTriStrip.Optimize(indices.ToArray()); // 頂点のボーン参照ローカルに変換 Vertex[] verts = vh.verts.ToArray(); for (int j = 0; j < verts.Length; ++j) { uint idx0 = verts[j].Idx; byte * idx = (byte *)(&idx0); Point4 wgt0 = verts[j].Wgt; float *wgt = (float *)(&wgt0); for (int k = 0; k < 4; ++k) { if (wgt[k] > float.Epsilon) { idx[k] = (byte)selected[idx[k]]; } } verts[j].Idx = idx0; } // サブメッシュ生成 TSOSubMesh sub = new TSOSubMesh(); sub.spec = mtl; sub.numbones = bones.Count; sub.bones = bones.ToArray(); sub.numvertices = nidx.Length; sub.vertices = new Vertex[nidx.Length]; for (int j = 0; j < nidx.Length; ++j) { sub.vertices[j] = verts[nidx[j]]; } Console.WriteLine(" {0,8} {1,12}", sub.vertices.Length, sub.bones.Length); subs.Add(sub); // 次の周回 List <int> t = faces1; faces1 = faces2; faces2 = t; t.Clear(); } #endregion // \todo TSOMesh生成 TSOMesh mesh = new TSOMesh(); mesh.name = i.name; mesh.numsubs = subs.Count; mesh.sub = subs.ToArray(); mesh.matrix = Matrix44.Identity; mesh.effect = 0; meshes.Add(mesh); } return(true); }
protected override bool DoGenerateMeshes() { meshes = new List <TSOMesh>(); foreach (MqoObject i in mqo.Objects) { if (i.name.ToLower() == "bone") { continue; } Console.WriteLine("object:" + i.name); // 法線生成 Point3[] nrm = new Point3[i.vertices.Count]; foreach (MqoFace j in i.faces) { Point3 v1 = Point3.Normalize(i.vertices[j.b] - i.vertices[j.a]); Point3 v2 = Point3.Normalize(i.vertices[j.c] - i.vertices[j.b]); Point3 n = Point3.Normalize(Point3.Cross(v1, v2)); nrm[j.a] -= n; nrm[j.b] -= n; nrm[j.c] -= n; } for (int j = 0; j < nrm.Length; ++j) { nrm[j] = Point3.Normalize(nrm[j]); } // ボーン情報作成 uint idx = 0x00000000; Point4 wgt = new Point4(1, 0, 0, 0); int[] bones = new int[1]; string bone = ObjectBoneNames[i.name]; bones[0] = nodes[bone].ID; // マテリアル別に処理を実行 List <ushort> indices = new List <ushort>(); VertexHeap <Vertex> vh = new VertexHeap <Vertex>(); List <TSOSubMesh> subs = new List <TSOSubMesh>(); Console.WriteLine(" vertices bone_indices"); Console.WriteLine(" -------- ------------"); for (int j = 0, n = materials.Count; j < n; ++j) { int mtl = j; indices.Clear(); foreach (MqoFace f in i.faces) { if (f.mtl != mtl) { continue; } Vertex va = new Vertex(i.vertices[f.a], wgt, idx, nrm[f.a], new Point2(f.ta.x, 1 - f.ta.y)); Vertex vb = new Vertex(i.vertices[f.b], wgt, idx, nrm[f.b], new Point2(f.tb.x, 1 - f.tb.y)); Vertex vc = new Vertex(i.vertices[f.c], wgt, idx, nrm[f.c], new Point2(f.tc.x, 1 - f.tc.y)); indices.Add(vh.Add(va)); indices.Add(vh.Add(vc)); indices.Add(vh.Add(vb)); } if (indices.Count == 0) { continue; } // フェイス最適化 ushort[] nidx = NvTriStrip.Optimize(indices.ToArray()); // サブメッシュ生成 Vertex[] verts = vh.verts.ToArray(); TSOSubMesh sub = new TSOSubMesh(); sub.spec = mtl; sub.numbones = bones.Length; sub.bones = bones; sub.numvertices = nidx.Length; sub.vertices = new Vertex[nidx.Length]; for (int k = 0; k < nidx.Length; ++k) { sub.vertices[k] = verts[nidx[k]]; } Console.WriteLine(" {0,8} {1,12}", sub.vertices.Length, sub.bones.Length); subs.Add(sub); } // メッシュ生成 TSOMesh mesh = new TSOMesh(); mesh.name = i.name; mesh.numsubs = subs.Count; mesh.sub = subs.ToArray(); mesh.matrix = Matrix44.Identity; mesh.effect = 0; meshes.Add(mesh); } return(true); }
protected override bool DoGenerateMeshes() { meshes = new List <TSOMesh>(); foreach (MqoObject obj in mqo.Objects) { if (obj.name.ToLower() == "bone") { continue; } Console.WriteLine("object:" + obj.name); obj.CreateNormal(); // ボーン情報作成 uint idx = 0x00000000; Point4 wgt = new Point4(1, 0, 0, 0); int[] bones = CreateBones(obj); // マテリアル別に処理を実行 List <ushort> vert_indices = new List <ushort>(); Heap <Vertex> vh = new Heap <Vertex>(); List <TSOSubMesh> subs = new List <TSOSubMesh>(); Console.WriteLine(" vertices bone_indices"); Console.WriteLine(" -------- ------------"); for (int spec = 0; spec < nummaterials; ++spec) { vert_indices.Clear(); foreach (MqoFace face in obj.faces) { if (face.spec != spec) { continue; } Vertex va = new Vertex(obj.vertices[face.a].Pos, wgt, idx, obj.vertices[face.a].Nrm, new Point2(face.ta.x, 1 - face.ta.y)); Vertex vb = new Vertex(obj.vertices[face.b].Pos, wgt, idx, obj.vertices[face.b].Nrm, new Point2(face.tb.x, 1 - face.tb.y)); Vertex vc = new Vertex(obj.vertices[face.c].Pos, wgt, idx, obj.vertices[face.c].Nrm, new Point2(face.tc.x, 1 - face.tc.y)); vert_indices.Add(vh.Add(va)); vert_indices.Add(vh.Add(vc)); vert_indices.Add(vh.Add(vb)); } if (vert_indices.Count == 0) { continue; } ushort[] optimized_indices = NvTriStrip.Optimize(vert_indices.ToArray()); TSOSubMesh sub = new TSOSubMesh(); sub.spec = spec; sub.numbones = bones.Length; sub.bones = bones; sub.numvertices = optimized_indices.Length; Vertex[] vertices = new Vertex[optimized_indices.Length]; for (int i = 0; i < optimized_indices.Length; ++i) { vertices[i] = vh.ary[optimized_indices[i]]; } sub.vertices = vertices; Console.WriteLine(" {0,8} {1,12}", sub.vertices.Length, sub.bones.Length); subs.Add(sub); } // メッシュ生成 TSOMesh mesh = new TSOMesh(); mesh.name = obj.name; mesh.numsubs = subs.Count; mesh.sub_meshes = subs.ToArray(); mesh.matrix = Matrix44.Identity; mesh.effect = 0; meshes.Add(mesh); } return(true); }