Ejemplo n.º 1
0
        /// <summary>
        /// Read a primitive object from a file
        /// </summary>
        /// <param name="file">The files contents as a byte array</param>
        /// <param name="address">The starting address of the primitive</param>
        /// <param name="indexFlags">How the indices of the loops are structured</param>
        public GCPrimitive(byte[] file, int address, GCIndexAttributeFlags indexFlags, out int end)
        {
            primitiveType = (GCPrimitiveType)file[address];

            bool wasBigEndian = ByteConverter.BigEndian;

            ByteConverter.BigEndian = true;

            ushort vtxCount = ByteConverter.ToUInt16(file, address + 1);

            // checking the flags
            bool hasFlag(GCIndexAttributeFlags flag)
            {
                return(indexFlags.HasFlag(flag));
            }

            // position always exists
            bool has_color  = hasFlag(GCIndexAttributeFlags.HasColor);
            bool has_normal = hasFlag(GCIndexAttributeFlags.HasNormal);
            bool has_uv     = hasFlag(GCIndexAttributeFlags.HasUV);

            //whether any of the indices use 16 bits instead of 8
            bool pos16bit = hasFlag(GCIndexAttributeFlags.Position16BitIndex);
            bool col16bit = hasFlag(GCIndexAttributeFlags.Color16BitIndex);
            bool nrm16bit = hasFlag(GCIndexAttributeFlags.Normal16BitIndex);
            bool uv16bit  = hasFlag(GCIndexAttributeFlags.UV16BitIndex);

            int tmpaddr = address + 3;

            loops = new List <Loop>();

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

                // reading position, which should always exist
                if (pos16bit)
                {
                    l.PositionIndex = ByteConverter.ToUInt16(file, tmpaddr);
                    tmpaddr        += 2;
                }
                else
                {
                    l.PositionIndex = file[tmpaddr];
                    tmpaddr++;
                }

                // reading normals
                if (has_normal)
                {
                    if (nrm16bit)
                    {
                        l.NormalIndex = ByteConverter.ToUInt16(file, tmpaddr);
                        tmpaddr      += 2;
                    }
                    else
                    {
                        l.NormalIndex = file[tmpaddr];
                        tmpaddr++;
                    }
                }

                // reading colors
                if (has_color)
                {
                    if (col16bit)
                    {
                        l.Color0Index = ByteConverter.ToUInt16(file, tmpaddr);
                        tmpaddr      += 2;
                    }
                    else
                    {
                        l.Color0Index = file[tmpaddr];
                        tmpaddr++;
                    }
                }

                // reading uvs
                if (has_uv)
                {
                    if (uv16bit)
                    {
                        l.UV0Index = ByteConverter.ToUInt16(file, tmpaddr);
                        tmpaddr   += 2;
                    }
                    else
                    {
                        l.UV0Index = file[tmpaddr];
                        tmpaddr++;
                    }
                }

                loops.Add(l);
            }

            end = tmpaddr;

            ByteConverter.BigEndian = wasBigEndian;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Write the contents
        /// </summary>
        /// <param name="writer">The output stream</param>
        /// <param name="indexFlags">How the indices of the loops are structured</param>
        public void Write(BinaryWriter writer, GCIndexAttributeFlags indexFlags)
        {
            writer.Write((byte)primitiveType);

            byte[] bytes = BitConverter.GetBytes((ushort)loops.Count);
            // writing count as big endian
            writer.Write(bytes[1]);
            writer.Write(bytes[0]);

            // checking the flags
            bool hasFlag(GCIndexAttributeFlags flag)
            {
                return(indexFlags.HasFlag(flag));
            }

            // position always exists
            bool has_color  = hasFlag(GCIndexAttributeFlags.HasColor);
            bool has_normal = hasFlag(GCIndexAttributeFlags.HasNormal);
            bool has_uv     = hasFlag(GCIndexAttributeFlags.HasUV);

            bool is_position_16bit = hasFlag(GCIndexAttributeFlags.Position16BitIndex);
            bool is_color_16bit    = hasFlag(GCIndexAttributeFlags.Color16BitIndex);
            bool is_normal_16bit   = hasFlag(GCIndexAttributeFlags.Normal16BitIndex);
            bool is_uv_16bit       = hasFlag(GCIndexAttributeFlags.UV16BitIndex);

            foreach (Loop v in loops)
            {
                // Position should always exist

                if (is_position_16bit)
                {
                    bytes = BitConverter.GetBytes(v.PositionIndex);
                    // writing big endian
                    writer.Write(bytes[1]);
                    writer.Write(bytes[0]);
                }
                else
                {
                    writer.Write((byte)v.PositionIndex);
                }

                if (has_normal)
                {
                    if (is_normal_16bit)
                    {
                        bytes = BitConverter.GetBytes(v.NormalIndex);
                        // writing big endian
                        writer.Write(bytes[1]);
                        writer.Write(bytes[0]);
                    }
                    else
                    {
                        writer.Write((byte)v.NormalIndex);
                    }
                }

                if (has_color)
                {
                    if (is_color_16bit)
                    {
                        bytes = BitConverter.GetBytes(v.Color0Index);
                        // writing big endian
                        writer.Write(bytes[1]);
                        writer.Write(bytes[0]);
                    }
                    else
                    {
                        writer.Write((byte)v.Color0Index);
                    }
                }

                if (has_uv)
                {
                    if (is_uv_16bit)
                    {
                        bytes = BitConverter.GetBytes(v.UV0Index);
                        // writing big endian
                        writer.Write(bytes[1]);
                        writer.Write(bytes[0]);
                    }
                    else
                    {
                        writer.Write((byte)v.UV0Index);
                    }
                }
            }
        }