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); } }
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); }