public GensWriter(Stream output, Encoding encoding,
                          HedgehogEngineHeader header, string mirageType = null,
                          bool isBigEndian = true) : base(output, encoding, isBigEndian)
        {
            if (!string.IsNullOrEmpty(mirageType) && header is MirageHeader mirageHeader)
            {
                mirageHeader.GenerateNodes(mirageType);
            }

            header.PrepareWrite(this);
        }
        public virtual void ImportXML(Stream fs)
        {
            var xml  = XDocument.Load(fs);
            var root = xml.Root;

            string headerType = root.GetAttrValue("headerType");

            headerType = headerType.ToLower();

            if (headerType == "mirage")
            {
                Header = new MirageHeader();
            }
            else
            {
                Header = new GensHeader();
            }

            Header.RootNodeType = root.GetUIntAttr("version");
            MaterialFlag        = root.GetByteAttr("flags");
            ShaderName          = root.GetElemValue("ShaderName");
            SubShaderName       = root.GetElemValue("SubShaderName");
            NoBackFaceCulling   = root.GetBoolElem("NoBackfaceCulling");
            AdditiveBlending    = root.GetBoolElem("AdditiveBlending");

            // Parameters
            var paramsElem = root.Element("Parameters");

            parameters.Clear();

            foreach (var paramElem in paramsElem.Elements())
            {
                parameters.Add(new Parameter(paramElem));
            }

            // Texset
            var texsetElem = root.Element("Texset");

            if (texsetElem != null)
            {
                TexsetName = root.GetAttrValue("externalName");
                Texset     = new GensTexset(texsetElem);
            }
        }
Exemple #3
0
        public virtual void Load(Stream fileStream, bool isTerrain, float scale = 1)
        {
            // Header
            var reader = new GensReader(fileStream);

            Header = reader.ReadHeader();

            // Data
            uint meshCount         = reader.ReadUInt32();
            uint meshOffsetsOffset = reader.ReadUInt32();

            if (isTerrain)
            {
                uint modelNameOffset = reader.ReadUInt32(); // TODO: Use this
                uint modelFlag       = reader.ReadUInt32(); // TODO: Use this
            }
            else
            {
                // TODO: Read the skeleton
            }

            // Mesh Offsets
            var meshOffsets = new uint[meshCount];

            reader.JumpTo(meshOffsetsOffset, false);

            for (uint i = 0; i < meshCount; ++i)
            {
                meshOffsets[i] = reader.ReadUInt32();
            }

            // Meshes
            for (uint i = 0; i < meshCount; ++i)
            {
                reader.JumpTo(meshOffsets[i], false);
                ReadMesh(reader, scale);
            }
        }
        public override void Load(Stream fileStream)
        {
            // Header
            var reader = new GensReader(fileStream);

            Header = reader.ReadHeader();

            // Root Node
            uint shaderOffset    = reader.ReadUInt32();
            uint subShaderOffset = reader.ReadUInt32();
            uint texsetOffset    = reader.ReadUInt32();
            uint texturesOffset  = reader.ReadUInt32();

            MaterialFlag      = reader.ReadByte(); // ?
            NoBackFaceCulling = reader.ReadBoolean();
            AdditiveBlending  = reader.ReadBoolean();
            UnknownFlag1      = reader.ReadByte();

            byte paramCount   = reader.ReadByte();
            byte padding1     = reader.ReadByte();
            byte unknownFlag2 = reader.ReadByte(); // Might be an enum, might just be a boolean?
            byte textureCount = reader.ReadByte();

            uint paramsOffset = reader.ReadUInt32();
            uint padding2     = reader.ReadUInt32();
            uint unknown1     = reader.ReadUInt32();

            // Padding/Unknown Value Checks
            if (padding1 != 0)
            {
                Console.WriteLine($"WARNING: Material Padding1 != 0 ({padding1})");
            }

            if (unknownFlag2 > 1)
            {
                Console.WriteLine($"WARNING: Material UnknownFlag2 > 1 ({unknownFlag2})");
            }

            if (padding2 != 0)
            {
                Console.WriteLine($"WARNING: Material Padding2 != 0 ({padding2})");
            }

            // Shader Name
            reader.JumpTo(shaderOffset, false);
            ShaderName = reader.ReadNullTerminatedString();

            // Sub-Shader Name
            reader.JumpTo(subShaderOffset, false);
            SubShaderName = reader.ReadNullTerminatedString();

            // Parameter Offsets
            var paramOffsets = new uint[paramCount];

            reader.JumpTo(paramsOffset, false);

            for (uint i = 0; i < paramCount; ++i)
            {
                paramOffsets[i] = reader.ReadUInt32();
            }

            // Parameters
            parameters.Clear();
            for (uint i = 0; i < paramCount; ++i)
            {
                reader.JumpTo(paramOffsets[i], false);
                var param = new Parameter()
                {
                    ParamFlag1 = reader.ReadUInt16(),
                    ParamFlag2 = reader.ReadUInt16()
                };

                uint paramNameOffset  = reader.ReadUInt32();
                uint paramValueOffset = reader.ReadUInt32();

                // Parameter Name
                reader.JumpTo(paramNameOffset, false);
                param.Name = reader.ReadNullTerminatedString();

                // Parameter Value
                reader.JumpTo(paramValueOffset, false);
                param.Value = reader.ReadVector4();

                parameters.Add(param);
            }

            // Texset
            reader.JumpTo(texsetOffset, false);
            if (Header.RootNodeType == 1) // TODO: Maybe check for textureCount < 1 instead?
            {
                TexsetName = reader.ReadNullTerminatedString();
            }
            else
            {
                Texset.Read(reader, textureCount);

                // Texture Offsets
                var texOffsets = new uint[textureCount];
                reader.JumpTo(texturesOffset, false);

                for (uint i = 0; i < textureCount; ++i)
                {
                    texOffsets[i] = reader.ReadUInt32();
                }

                // Textures
                for (int i = 0; i < textureCount; ++i)
                {
                    reader.JumpTo(texOffsets[i], false);
                    Texset.Textures[i].Read(reader);
                }
            }
        }
        // Methods
        public void FinishWrite(HedgehogEngineHeader header,
                                string mirageType = null, bool writeEOFNull = true)
        {
            // Write Footer and Update Header Values
            uint footerPos = (uint)BaseStream.Position;

            if (header is GensHeader gensHeader)
            {
                WriteFooter(true, writeEOFNull);

                header.FooterOffset     = footerPos;
                gensHeader.RootNodeSize = (footerPos - Offset);
                gensHeader.FileSize     = (uint)BaseStream.Position;
            }
            else if (header is MirageHeader mirageHeader)
            {
                FixPadding(16);

                uint footerPosPadded = (uint)BaseStream.Position;
                uint len             = MirageHeader.Node.Length;

                header.FooterOffset = footerPosPadded;
                WriteFooter(false, writeEOFNull);

                // Update Sizes
                uint fileSize = (uint)BaseStream.Position;
                mirageHeader.FooterOffsetsCount = (uint)offsets.Count;
                mirageHeader.RootNode.DataSize  = fileSize;

                if (!string.IsNullOrEmpty(mirageType))
                {
                    MirageHeader.Node typeNode, contextsNode;
                    typeNode = mirageHeader.GetNode(mirageType, false);

                    if (typeNode != null)
                    {
                        UpdateSize(typeNode, footerPosPadded);
                        contextsNode = typeNode.GetNode(MirageHeader.Contexts, false);

                        if (contextsNode != null)
                        {
                            UpdateSize(contextsNode, footerPos);
                        }
                    }
                }

                // Sub-Methods
                void UpdateSize(MirageHeader.Node node, uint endPos)
                {
                    if (node.DataSize == 0)
                    {
                        node.DataSize = (endPos - len);
                    }

                    len += MirageHeader.Node.Length;
                }
            }

            // Write Header
            BaseStream.Position = 0;
            header.FinishWrite(this);
        }