public GXDisplayList(byte[] Buffer, HSD_AttributeGroup Group) { if (Buffer == null) { return; } HSDReader Reader = new HSDReader(new MemoryStream(Buffer)); while (Reader.Position() < Buffer.Length) { GXPrimitiveGroup g = new GXPrimitiveGroup(); if (!g.Read(Reader, Group)) { break; } Primitives.Add(g); } Reader.Close(); }
public static GXVertex[] GetDecodedVertices(GXPrimitiveGroup PrimitiveGroup, HSD_AttributeGroup Group) { // Create Vertex List List <GXVertex> Vertices = new List <GXVertex>(); // Prepare vertex buffers for reading Dictionary <GXVertexBuffer, HSDReader> Buffers = new Dictionary <GXVertexBuffer, HSDReader>(); foreach (GXVertexBuffer buffer in Group.Attributes) { Buffers.Add(buffer, buffer.DataBuffer == null ? null : new HSDReader(new MemoryStream(buffer.DataBuffer))); } // Decode foreach (GXIndexGroup ig in PrimitiveGroup.Indices) { GXVertex Vertex = new GXVertex(); for (int i = 0; i < Group.Attributes.Count; i++) { GXVertexBuffer Attr = Group.Attributes[i]; HSDReader VertexBuffer = Buffers[Attr]; int index = ig.Indices[i]; float[] f = new float[0]; if (VertexBuffer != null) { VertexBuffer.Seek((uint)(Attr.Stride * index)); f = Read(VertexBuffer, Attr.CompType, Attr.Stride); } switch (Attr.Name) { case GXAttribName.GX_VA_PNMTXIDX: Vertex.PMXID = (ushort)index; break; case GXAttribName.GX_VA_TEX0MTXIDX: Vertex.TEX0MTXIDX = (ushort)index; break; case GXAttribName.GX_VA_POS: Vertex.Pos.X = f[0] / (float)Math.Pow(2, Attr.Scale); Vertex.Pos.Y = f[1] / (float)Math.Pow(2, Attr.Scale); Vertex.Pos.Z = f[2] / (float)Math.Pow(2, Attr.Scale); break; case GXAttribName.GX_VA_NRM: Vertex.Nrm.X = f[0] / (float)Math.Pow(2, Attr.Scale); Vertex.Nrm.Y = f[1] / (float)Math.Pow(2, Attr.Scale); Vertex.Nrm.Z = f[2] / (float)Math.Pow(2, Attr.Scale); break; case GXAttribName.GX_VA_TEX0: Vertex.TEX0.X = f[0] / (float)Math.Pow(2, Attr.Scale); Vertex.TEX0.Y = f[1] / (float)Math.Pow(2, Attr.Scale); break; case GXAttribName.GX_VA_TEX1: Vertex.TEX1.X = f[0] / (float)Math.Pow(2, Attr.Scale); Vertex.TEX1.Y = f[1] / (float)Math.Pow(2, Attr.Scale); break; case GXAttribName.GX_VA_CLR0: if (Attr.AttributeType == GXAttribType.GX_DIRECT) { Vertex.Clr0.R = ig.Clr0[0] / 255f; Vertex.Clr0.G = ig.Clr0[1] / 255f; Vertex.Clr0.B = ig.Clr0[2] / 255f; Vertex.Clr0.A = ig.Clr0[3] / 255f; } if (Attr.AttributeType == GXAttribType.GX_INDEX8) { Vertex.Clr0.R = f[0]; Vertex.Clr0.G = f[1]; Vertex.Clr0.B = f[2]; Vertex.Clr0.A = f[3]; } break; case GXAttribName.GX_VA_CLR1: if (Attr.AttributeType == GXAttribType.GX_DIRECT) { Vertex.Clr1.R = ig.Clr1[0] / 255f; Vertex.Clr1.G = ig.Clr1[1] / 255f; Vertex.Clr1.B = ig.Clr1[2] / 255f; Vertex.Clr1.A = ig.Clr1[3] / 255f; } if (Attr.AttributeType == GXAttribType.GX_INDEX8) { Vertex.Clr1.R = f[0]; Vertex.Clr1.G = f[1]; Vertex.Clr1.B = f[2]; Vertex.Clr1.A = f[3]; } break; default: Console.WriteLine("To be implemented: " + Attr.Name); break; } } Vertices.Add(Vertex); } foreach (var b in Buffers) { if (b.Value != null) { b.Value.Dispose(); } } return(Vertices.ToArray()); }
/// <summary> /// Creates a primitive group for the vertex buffer /// </summary> /// <param name="type"></param> /// <param name="Vertices"></param> /// <param name="Attributes"></param> /// <returns></returns> public GXPrimitiveGroup Compress(GXPrimitiveType type, GXVertex[] Vertices, HSD_AttributeGroup Attributes) { GXPrimitiveGroup g = new GXPrimitiveGroup(); g.PrimitiveType = type; g.Indices = new GXIndexGroup[Vertices.Length]; int IndexGroupIndex = 0; foreach (GXVertex v in Vertices) { GXIndexGroup ig = new GXIndexGroup(); ig.Indices = new ushort[Attributes.Attributes.Count]; int i = 0; foreach (GXVertexBuffer b in Attributes.Attributes) { switch (b.AttributeType) { case GXAttribType.GX_DIRECT: if (b.Name == GXAttribName.GX_VA_CLR0) { ig.Clr0 = new byte[] { (byte)(v.Clr0.R * 0xFF), (byte)(v.Clr0.G * 0xFF), (byte)(v.Clr0.B * 0xFF), (byte)(v.Clr0.A * 0xFF) } } ; else if (b.Name == GXAttribName.GX_VA_CLR1) { ig.Clr1 = new byte[] { (byte)(v.Clr1.R * 0xFF), (byte)(v.Clr1.G * 0xFF), (byte)(v.Clr1.B * 0xFF), (byte)(v.Clr1.A * 0xFF) } } ; else if (b.Name == GXAttribName.GX_VA_PNMTXIDX) { ig.Indices[i] = v.PMXID; } if (b.Name == GXAttribName.GX_VA_TEX0MTXIDX) { ig.Indices[i] = v.TEX0MTXIDX; } break; default: switch (b.Name) { case GXAttribName.GX_VA_POS: ig.Indices[i] = GetIndex(b, v.Pos); break; case GXAttribName.GX_VA_NRM: ig.Indices[i] = GetIndex(b, v.Nrm); break; case GXAttribName.GX_VA_TEX0: ig.Indices[i] = GetIndex(b, v.TEX0); break; case GXAttribName.GX_VA_TEX1: ig.Indices[i] = GetIndex(b, v.TEX1); break; case GXAttribName.GX_VA_CLR0: ig.Indices[i] = GetIndex(b, v.Clr0); break; default: throw new Exception("Error Building " + b.Name); } break; } i++; } g.Indices[IndexGroupIndex++] = ig; } return(g); }