Example #1
0
        public bool Read(HSDReader Reader, HSD_AttributeGroup Attributes)
        {
            PrimitiveType = (GXPrimitiveType)Reader.ReadByte();
            if (PrimitiveType == 0)
            {
                return(false);
            }
            Count   = Reader.ReadUInt16();
            Indices = new GXIndexGroup[Count];
            for (int j = 0; j < Count; j++)
            {
                GXIndexGroup g = new GXIndexGroup();
                g.Indices = new ushort[Attributes.Attributes.Count];
                int i = 0;
                Indices[j] = g;
                foreach (GXVertexBuffer att in Attributes.Attributes)
                {
                    switch (att.AttributeType)
                    {
                    case GXAttribType.GX_DIRECT:
                        if (att.Name == GXAttribName.GX_VA_CLR0)
                        {
                            g.Clr0 = ReadGXClr(Reader, (int)att.CompType);
                        }
                        else if (att.Name == GXAttribName.GX_VA_CLR1)
                        {
                            g.Clr1 = ReadGXClr(Reader, (int)att.CompType);
                        }
                        else
                        {
                            g.Indices[i] = Reader.ReadByte();
                        }
                        break;

                    case GXAttribType.GX_INDEX8:
                        g.Indices[i] = Reader.ReadByte();
                        break;

                    case GXAttribType.GX_INDEX16:
                        g.Indices[i] = Reader.ReadUInt16();
                        break;
                    }
                    i++;
                }
            }
            return(true);
        }
Example #2
0
        public byte[] ToBuffer(HSD_AttributeGroup Group)
        {
            MemoryStream o      = new MemoryStream();
            HSDWriter    Writer = new HSDWriter(o);

            foreach (GXPrimitiveGroup g in Primitives)
            {
                g.Write(Writer, Group);
            }
            Writer.Write((byte)0);

            Writer.Align(0x20);

            Writer.Close();
            byte[] bytes = o.ToArray();
            o.Close();

            return(bytes);
        }
Example #3
0
        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();
        }
Example #4
0
        public void Write(HSDWriter Writer, HSD_AttributeGroup Attributes)
        {
            Writer.Write((byte)PrimitiveType);
            Writer.Write((ushort)Indices.Length);
            foreach (GXIndexGroup ig in Indices)
            {
                GXIndexGroup g = ig;
                int          i = 0;
                foreach (GXVertexBuffer att in Attributes.Attributes)
                {
                    switch (att.AttributeType)
                    {
                    case GXAttribType.GX_DIRECT:
                        if (att.Name != GXAttribName.GX_VA_CLR0)
                        {
                            Writer.Write((byte)g.Indices[i]);
                        }
                        else if (att.Name == GXAttribName.GX_VA_CLR0)
                        {
                            WriteGXClr(g.Clr0, Writer, att.CompType);
                        }
                        else if (att.Name == GXAttribName.GX_VA_CLR1)
                        {
                            WriteGXClr(g.Clr1, Writer, att.CompType);
                        }
                        break;

                    case GXAttribType.GX_INDEX8:
                        Writer.Write((byte)g.Indices[i]);
                        break;

                    case GXAttribType.GX_INDEX16:
                        Writer.Write(g.Indices[i]);
                        break;
                    }
                    i++;
                }
            }
        }
Example #5
0
        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());
        }
Example #6
0
        /// <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);
        }
Example #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="triList"></param>
        /// <param name="attrGroup"></param>
        /// <param name="weights"></param>
        public HSD_POBJ CreatePOBJ(List <GXVertex> triList, HSD_AttributeGroup attrGroup, List <HSD_JOBJWeight> weights)
        {
            TriangleConverter.TriangleConverter converter = new TriangleConverter.TriangleConverter(true, 100, 3, true);
            int pointCount, faceCount;

            var groups = converter.GroupPrimitives(triList.ToArray(), out pointCount, out faceCount);

            HSD_POBJ rootPOBJ = null;
            HSD_POBJ prevPOBJ = null;

            foreach (var g in groups)
            {
                var jobjweights = new List <HSD_JOBJWeight>();
                var pmidToNewID = new Dictionary <ushort, ushort>();

                foreach (var n in g._nodes)
                {
                    pmidToNewID.Add(n, (ushort)(jobjweights.Count * 3));
                    jobjweights.Add(weights[n / 3]);
                }

                GXDisplayList newdl = new GXDisplayList();

                foreach (var t in g._triangles)
                {
                    var newVert = new List <GXVertex>();
                    for (int p = 0; p < t.Points.Count; p++)
                    {
                        var point = t.Points[p];
                        point.PMXID = pmidToNewID[point.PMXID];
                        t.Points[p] = point;
                        newVert.Add(point);
                        //Console.WriteLine(t.points[p].PMID + " " + point.PMXID + " " + pmidToNewID[point.PMXID] + " " + jobjweights.Count);
                    }

                    newdl.Primitives.Add(Compress(GXPrimitiveType.Triangles, newVert.ToArray(), attrGroup));
                }
                foreach (var t in g._tristrips)
                {
                    var newVert = new List <GXVertex>();
                    for (int p = 0; p < t.Points.Count; p++)
                    {
                        //Console.WriteLine(t.Points[p].PMXID + " " + g._nodes.Count);
                        var point = t.Points[p];
                        point.PMXID = pmidToNewID[point.PMXID];
                        t.Points[p] = point;
                        newVert.Add(point);
                    }
                    newdl.Primitives.Add(Compress(GXPrimitiveType.TriangleStrip, newVert.ToArray(), attrGroup));
                }

                HSD_PointerArray <HSD_JOBJWeight> bindWeights = new HSD_PointerArray <HSD_JOBJWeight>();
                bindWeights.Elements = jobjweights.ToArray();

                var newpobj = new HSD_POBJ();

                newpobj.Flags             = POBJ_FLAG.ENVELOPE;
                newpobj.BindGroups        = bindWeights;
                newpobj.VertexAttributes  = attrGroup;
                newpobj.DisplayListBuffer = newdl.ToBuffer(attrGroup);

                if (prevPOBJ == null)
                {
                    rootPOBJ = newpobj;
                }
                else
                {
                    prevPOBJ.Next = newpobj;
                }
                prevPOBJ = newpobj;
            }

            return(rootPOBJ);
        }