예제 #1
0
파일: Poly.cs 프로젝트: X-Hax/SA3D
        /// <summary>
        /// Read a primitive object from a file
        /// </summary>
        /// <param name="source">The files contents as a byte array</param>
        /// <param name="address">The starting address of the primitive</param>
        /// <param name="indexAttribs">How the indices of the loops are structured</param>
        public static Poly Read(byte[] source, ref uint address, IndexAttributes indexAttribs)
        {
            PushBigEndian(true);

            PolyType type     = (PolyType)source[address];
            ushort   vtxCount = source.ToUInt16(address + 1);

            // checking the attributes
            bool hasFlag(IndexAttributes attrib) => indexAttribs.HasFlag(attrib);

            // position always exists
            bool hasCol = hasFlag(IndexAttributes.HasColor);
            bool hasNrm = hasFlag(IndexAttributes.HasNormal);
            bool hasUV  = hasFlag(IndexAttributes.HasUV);

            //whether any of the indices use 16 bits instead of 8
            bool shortPos = hasFlag(IndexAttributes.Position16BitIndex);
            bool shortCol = hasFlag(IndexAttributes.Color16BitIndex);
            bool shortNrm = hasFlag(IndexAttributes.Normal16BitIndex);
            bool shortUV  = hasFlag(IndexAttributes.UV16BitIndex);

            address += 3;

            List <Corner> corners = new();

            for (ushort i = 0; i < vtxCount; i++)
            {
                Corner l = new();

                // reading position, which should always exist
                if (shortPos)
                {
                    l.PositionIndex = source.ToUInt16(address);
                    address        += 2;
                }
                else
                {
                    l.PositionIndex = source[address];
                    address++;
                }

                // reading normals
                if (hasNrm)
                {
                    if (shortNrm)
                    {
                        l.NormalIndex = source.ToUInt16(address);
                        address      += 2;
                    }
                    else
                    {
                        l.NormalIndex = source[address];
                        address++;
                    }
                }

                // reading colors
                if (hasCol)
                {
                    if (shortCol)
                    {
                        l.Color0Index = source.ToUInt16(address);
                        address      += 2;
                    }
                    else
                    {
                        l.Color0Index = source[address];
                        address++;
                    }
                }

                // reading uvs
                if (hasUV)
                {
                    if (shortUV)
                    {
                        l.UV0Index = source.ToUInt16(address);
                        address   += 2;
                    }
                    else
                    {
                        l.UV0Index = source[address];
                        address++;
                    }
                }

                corners.Add(l);
            }

            PopEndian();
            return(new Poly(type, corners.ToArray()));
        }
예제 #2
0
파일: Poly.cs 프로젝트: X-Hax/SA3D
        /// <summary>
        /// Write the contents
        /// </summary>
        /// <param name="writer">The output stream</param>
        /// <param name="indexAttribs">How the indices of the loops are structured</param>
        public void Write(EndianWriter writer, IndexAttributes indexAttribs)
        {
            writer.PushBigEndian(true);

            writer.Write((byte)Type);
            writer.Write((ushort)Corners.Length);

            // checking the attributes
            bool hasFlag(IndexAttributes attrib) => indexAttribs.HasFlag(attrib);

            // position always exists
            bool hasCol = hasFlag(IndexAttributes.HasColor);
            bool hasNrm = hasFlag(IndexAttributes.HasNormal);
            bool hasUV  = hasFlag(IndexAttributes.HasUV);

            bool shortPos = hasFlag(IndexAttributes.Position16BitIndex);
            bool shortCol = hasFlag(IndexAttributes.Color16BitIndex);
            bool shortNrm = hasFlag(IndexAttributes.Normal16BitIndex);
            bool shortUV  = hasFlag(IndexAttributes.UV16BitIndex);

            foreach (Corner v in Corners)
            {
                // Position should always exist
                if (shortPos)
                {
                    writer.Write(v.PositionIndex);
                }
                else
                {
                    writer.Write((byte)v.PositionIndex);
                }

                if (hasNrm)
                {
                    if (shortNrm)
                    {
                        writer.Write(v.NormalIndex);
                    }
                    else
                    {
                        writer.Write((byte)v.NormalIndex);
                    }
                }

                if (hasCol)
                {
                    if (shortCol)
                    {
                        writer.Write(v.Color0Index);
                    }
                    else
                    {
                        writer.Write((byte)v.Color0Index);
                    }
                }

                if (hasUV)
                {
                    if (shortUV)
                    {
                        writer.Write(v.UV0Index);
                    }
                    else
                    {
                        writer.Write((byte)v.UV0Index);
                    }
                }
            }

            writer.PopEndian();
        }