Esempio n. 1
0
        /// <summary>
        /// Writes the parameters and primitives to a stream
        /// </summary>
        /// <param name="writer">The ouput stream</param>
        /// <param name="indexFlags">The index flags</param>
        public void WriteData(BinaryWriter writer, GCIndexAttributeFlags indexFlags)
        {
            paramAddress = (uint)writer.BaseStream.Length;

            foreach (GCParameter param in parameters)
            {
                param.Write(writer);
            }

            primitiveAddress = (uint)writer.BaseStream.Length;

            foreach (GCPrimitive prim in primitives)
            {
                prim.Write(writer, indexFlags);
            }

            primitiveSize = (uint)writer.BaseStream.Length - primitiveAddress;
        }
Esempio n. 2
0
        /// <summary>
        /// Read a mesh from a file
        /// </summary>
        /// <param name="file">The files contents</param>
        /// <param name="address">The address at which the mesh is located</param>
        /// <param name="imageBase">The imagebase (used for when reading from an exe)</param>
        /// <param name="index">Indexattribute parameter of the previous mesh</param>
        public GCMesh(byte[] file, int address, uint imageBase, GCIndexAttributeFlags indexFlags)
        {
            // getting the addresses and sizes
            int parameters_offset = (int)(ByteConverter.ToInt32(file, address) - imageBase);
            int parameters_count  = ByteConverter.ToInt32(file, address + 4);

            int primitives_offset = (int)(ByteConverter.ToInt32(file, address + 8) - imageBase);
            int primitives_size   = ByteConverter.ToInt32(file, address + 12);

            // reading the parameters
            parameters = new List <GCParameter>();
            for (int i = 0; i < parameters_count; i++)
            {
                parameters.Add(GCParameter.Read(file, parameters_offset));
                parameters_offset += 8;
            }

            // getting the index attribute parameter
            GCIndexAttributeFlags?flags = IndexFlags;

            if (flags.HasValue)
            {
                indexFlags = flags.Value;
            }

            // reading the primitives
            primitives = new List <GCPrimitive>();
            int end_pos = primitives_offset + primitives_size;

            while (primitives_offset < end_pos)
            {
                // if the primitive isnt valid
                if (file[primitives_offset] == 0)
                {
                    break;
                }
                primitives.Add(new GCPrimitive(file, primitives_offset, indexFlags, out primitives_offset));
            }
        }
Esempio n. 3
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;
        }
Esempio n. 4
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);
                    }
                }
            }
        }
Esempio n. 5
0
        public GCAttach(byte[] file, int address, uint imageBase, Dictionary <int, string> labels)
        {
            if (labels.ContainsKey(address))
            {
                Name = labels[address];
            }
            else
            {
                Name = "attach_" + address.ToString("X8");
            }

            // The struct is 36/0x24 bytes long

            uint vertexAddress = ByteConverter.ToUInt32(file, address) - imageBase;
            //uint gap = ByteConverter.ToUInt32(file, address + 4);
            int opaqueAddress      = (int)(ByteConverter.ToInt32(file, address + 8) - imageBase);
            int translucentAddress = (int)(ByteConverter.ToInt32(file, address + 12) - imageBase);

            int opaqueCount      = ByteConverter.ToInt16(file, address + 16);
            int translucentCount = ByteConverter.ToInt16(file, address + 18);

            Bounds = new BoundingSphere(file, address + 20);

            // reading vertex data
            vertexData = new List <GCVertexSet>();
            GCVertexSet vertexSet = new GCVertexSet(file, vertexAddress, imageBase);

            while (vertexSet.attribute != GCVertexAttribute.Null)
            {
                vertexData.Add(vertexSet);
                vertexAddress += 16;
                vertexSet      = new GCVertexSet(file, vertexAddress, imageBase);
            }

            // reading geometry
            GCIndexAttributeFlags indexFlags = GCIndexAttributeFlags.HasPosition;

            opaqueMeshes = new List <GCMesh>();
            for (int i = 0; i < opaqueCount; i++)
            {
                GCMesh mesh = new GCMesh(file, opaqueAddress, imageBase, indexFlags);

                GCIndexAttributeFlags?t = mesh.IndexFlags;
                if (t.HasValue)
                {
                    indexFlags = t.Value;
                }

                opaqueMeshes.Add(mesh);
                opaqueAddress += 16;
            }

            translucentMeshes = new List <GCMesh>();
            for (int i = 0; i < translucentCount; i++)
            {
                GCMesh mesh = new GCMesh(file, translucentAddress, imageBase, indexFlags);

                GCIndexAttributeFlags?t = mesh.IndexFlags;
                if (t.HasValue)
                {
                    indexFlags = t.Value;
                }

                translucentMeshes.Add(mesh);
                translucentAddress += 16;
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Writes the attaches contents into a byte array
        /// </summary>
        /// <param name="imageBase">The files imagebase</param>
        /// <param name="DX">Unused</param>
        /// <param name="labels">The files labels</param>
        /// <param name="address"></param>
        /// <returns></returns>
        public override byte[] GetBytes(uint imageBase, bool DX, Dictionary <string, uint> labels, out uint address)
        {
            byte[] output;

            using (MemoryStream strm = new MemoryStream())
            {
                BinaryWriter writer = new BinaryWriter(strm);

                writer.Write(new byte[16]);                 // address placeholders
                writer.Write((ushort)opaqueMeshes.Count);
                writer.Write((ushort)translucentMeshes.Count);
                writer.Write(Bounds.GetBytes());

                // writing vertex data
                foreach (GCVertexSet vtx in vertexData)
                {
                    vtx.WriteData(writer);
                }

                uint vtxAddr = (uint)writer.BaseStream.Length + imageBase;

                // writing vertex attributes
                foreach (GCVertexSet vtx in vertexData)
                {
                    vtx.WriteAttribute(writer, imageBase);
                }
                writer.Write((byte)255);
                writer.Write(new byte[15]);                 // empty vtx attribute

                // writing geometry data
                GCIndexAttributeFlags indexFlags = GCIndexAttributeFlags.HasPosition;
                foreach (GCMesh m in opaqueMeshes)
                {
                    GCIndexAttributeFlags?t = m.IndexFlags;
                    if (t.HasValue)
                    {
                        indexFlags = t.Value;
                    }
                    m.WriteData(writer, indexFlags);
                }
                foreach (GCMesh m in translucentMeshes)
                {
                    GCIndexAttributeFlags?t = m.IndexFlags;
                    if (t.HasValue)
                    {
                        indexFlags = t.Value;
                    }
                    m.WriteData(writer, indexFlags);
                }

                // writing geometry properties
                uint opaqueAddress = (uint)writer.BaseStream.Length + imageBase;
                foreach (GCMesh m in opaqueMeshes)
                {
                    m.WriteProperties(writer, imageBase);
                }
                uint translucentAddress = (uint)writer.BaseStream.Length + imageBase;
                foreach (GCMesh m in translucentMeshes)
                {
                    m.WriteProperties(writer, imageBase);
                }

                // replacing the placeholders
                writer.Seek(0, SeekOrigin.Begin);
                writer.Write(vtxAddr);
                writer.Write(0);
                writer.Write(opaqueAddress);
                writer.Write(translucentAddress);
                writer.Seek(0, SeekOrigin.End);

                output = strm.ToArray();
            }

            address = 0;
            labels.Add(Name, imageBase);
            return(output);
        }
Esempio n. 7
0
 /// <summary>
 /// Creates an index attribute parameter based on existing flags
 /// </summary>
 /// <param name="flags"></param>
 public IndexAttributeParameter(GCIndexAttributeFlags flags) : base(ParameterType.IndexAttributeFlags)
 {
     IndexAttributes = flags;
 }
Esempio n. 8
0
 /// <summary>
 /// Creates an empty index attribute parameter
 /// </summary>
 public IndexAttributeParameter() : base(ParameterType.IndexAttributeFlags)
 {
     //this always exists
     IndexAttributes &= GCIndexAttributeFlags.HasPosition;
 }