public void ExportAs(object sender, EventArgs args) { using (var sfd = new SaveFileDialog()) { sfd.Filter = "Source Model|*.smd|" + "All Files (*.*)|*.*"; sfd.DefaultExt = "smd"; if (sfd.ShowDialog() == DialogResult.OK) { GXVertexDecompressor decom = new GXVertexDecompressor(Root); SMD smd = new SMD(); smd.Bones = RenderBones; foreach (MeleeDataObjectNode n in DataObjects.Nodes) { int[] ind; List <GXVertex> verts; n.GetVerticesAsTriangles(out ind, out verts); for (int i = 0; i < ind.Length; i += 3) { SMDTriangle t = new SMDTriangle(); t.Material = "defaultmaterial"; t.v1 = GXVertexToSMDVertex(verts[ind[i]]); t.v2 = GXVertexToSMDVertex(verts[ind[i + 1]]); t.v3 = GXVertexToSMDVertex(verts[ind[i + 2]]); smd.Triangles.Add(t); } } smd.Save(sfd.FileName); } } }
public void RecompileVertices(GXVertexCompressor compressor) { GXVertexDecompressor decompressor = new GXVertexDecompressor(Root); foreach (MeleeDataObjectNode n in DataObjects.Nodes) { n.RecompileVertices(decompressor, compressor); } }
public void GetVerticesAsTriangles(out int[] indices, out List <GXVertex> Verts) { Verts = new List <GXVertex>(); List <int> ind = new List <int>(); VBN Bones = GetRoot().RenderBones; GXVertexDecompressor decompressor = new GXVertexDecompressor(GetRoot().Root); int index = 0; foreach (DatPolygon p in DOBJ.Polygons) { foreach (GXDisplayList dl in p.DisplayLists) { GXVertex[] verts = decompressor.GetFormattedVertices(dl, p); for (int i = 0; i < verts.Length; i++) { if (verts[i].N != null && verts[i].N.Length == 1) { /*Vector3 ToTransform = Vector3.TransformPosition(new Vector3(verts[i].Pos.X, verts[i].Pos.Y, verts[i].Pos.Z), Bones.bones[verts[i].N[0]].transform); * verts[i].Pos.X = ToTransform.X; * verts[i].Pos.Y = ToTransform.Y; * verts[i].Pos.Z = ToTransform.Z; * Vector3 ToTransformN = Vector3.TransformNormal(new Vector3(verts[i].Nrm.X, verts[i].Nrm.Y, verts[i].Nrm.Z), Bones.bones[verts[i].N[0]].transform); * verts[i].Nrm.X = ToTransformN.X; * verts[i].Nrm.Y = ToTransformN.Y; * verts[i].Nrm.Z = ToTransformN.Z;*/ } // TODO: Transform by attached jobj } Verts.AddRange(verts); List <int> indi = new List <int>(); for (int i = 0; i < dl.Indices.Length; i++) { indi.Add(index + i); } switch (dl.PrimitiveType) { case GXPrimitiveType.TriangleStrip: ind.AddRange(TriangleTools.fromTriangleStrip(indi)); break; case GXPrimitiveType.Quads: ind.AddRange(TriangleTools.fromQuad(indi)); break; case GXPrimitiveType.Triangles: ind.AddRange(indi); break; default: Console.WriteLine("Warning: unsupported primitive type " + dl.PrimitiveType.ToString()); ind.AddRange(indi); break; } index += indi.Count; } } indices = ind.ToArray(); }
public void RecompileVertices(GXVertexDecompressor decompressor, GXVertexCompressor compressor) { if (VertsToImport != null) { for (int p = 0; p < VertsToImport.Count; p++) { if (p >= DOBJ.Polygons.Count) { MessageBox.Show("Error injecting vertices into DOBJ: Not enough polygons"); return; } DatPolygon poly = DOBJ.Polygons[p]; List <GXDisplayList> newDL = new List <GXDisplayList>(); // maximize vertex groups int size = 3; for (int i = 0; i < VertsToImport[p].Length; i += size) { List <GXVertex> VertList = new List <GXVertex>(); for (int j = 0; j < size; j += 3) { VertList.AddRange(new GXVertex[] { VertsToImport[p][i + j + 2], VertsToImport[p][i + j + 1], VertsToImport[p][i + j] }); } newDL.Add(compressor.CompressDisplayList( VertList.ToArray(), GXPrimitiveType.Triangles, poly.AttributeGroup)); } poly.DisplayLists = newDL; } VertsToImport = null; } else { foreach (DatPolygon p in DOBJ.Polygons) { List <GXDisplayList> newDL = new List <GXDisplayList>(); foreach (GXDisplayList dl in p.DisplayLists) { newDL.Add(compressor.CompressDisplayList( decompressor.GetFormattedVertices(dl, p), dl.PrimitiveType, p.AttributeGroup)); } p.DisplayLists = newDL; } } }
private static void AddVertexContainer(GXVertexDecompressor decom, List <IndexedVertexData <MeleeVertex> > vertexContainers, DatPolygon polygon, GXDisplayList displayList) { List <MeleeVertex> vertices = new List <MeleeVertex>(); List <int> vertexIndices = new List <int>(); for (int i = 0; i < displayList.Indices.Length; i++) { vertexIndices.Add(i); } vertices.AddRange(ConvertVerts(decom.GetFormattedVertices(displayList, polygon))); PrimitiveType primitiveType = MeleeDatToOpenGL.GetGLPrimitiveType(displayList.PrimitiveType); var vertexContainer = new IndexedVertexData <MeleeVertex>(vertices, vertexIndices, primitiveType); vertexContainers.Add(vertexContainer); }
private void RefreshRenderMeshes() { renderMeshes.Clear(); GXVertexDecompressor decom = new GXVertexDecompressor(GetRoot().Root); var vertexContainers = new List <IndexedVertexData <MeleeVertex> >(); // Each display list can have a different primitive type, so we need to generate a lot of containers. foreach (DatPolygon polygon in DOBJ.Polygons) { foreach (GXDisplayList displayList in polygon.DisplayLists) { AddVertexContainer(decom, vertexContainers, polygon, displayList); } } // Combine vertex containers with the same primitive type. // The optimization doesn't work properly for all primitive types yet. GroupContainersCreateRenderMeshes(vertexContainers); }