private static MDLTexture ReadMDLTexture(BinaryReader br, int offset) { br.BaseStream.Seek(offset, SeekOrigin.Begin); MDLTexture tex = new MDLTexture(); tex.tex_name_offset = br.ReadInt32(); tex.tex_flags = br.ReadInt32(); tex.tex_used = br.ReadInt32(); tex.unused_1 = br.ReadInt32(); tex.tex_material = br.ReadInt32(); tex.client_material = br.ReadInt32(); tex.unused_array = new int[10]; // 10 for (int i = 0; i < 10; i++) { tex.unused_array[i] = br.ReadInt32(); } return tex; }
public static bool ReadFile(string filename) { // Check filename and if file exists if (!filename.EndsWith(".mdl") || !Path.HasExtension(filename)) { System.Console.WriteLine("[MDLReader] Filename not accepted. (file:{0})", filename); return false; } FCFile file = FileCache.Instance.GetFile(filename); if (file == null) { System.Console.WriteLine("[MDLReader] MDL file not found. (file:{0})", filename); return false; } srcModel = new SourceModel(); using (FileStream stream = File.OpenRead(file.FullName)) { // Read header BinaryReader br = new BinaryReader(stream); MDLHeader header = ReadHeader(br); // Check magic number if (header.magic_number != MDLHeader.MDL_MAGIC_NUMBER) { System.Console.WriteLine("[MDLReader] Bad Magic number (file:{0})", filename); return false; } // Read texture paths string[] texturePaths = new string[header.num_texture_paths]; StringBuilder strBuilder = new StringBuilder(256); for (int i = 0; i < header.num_texture_paths; i++) { // Seek to offset index int indexoffset = header.texture_path_offset + (i * sizeof(int)); br.BaseStream.Seek(indexoffset, SeekOrigin.Begin); // Get offset for this texture path int texoffset = br.ReadInt32(); br.BaseStream.Seek(texoffset, SeekOrigin.Begin); // Read name until \0 char is met char curChar; while((curChar = br.ReadChar()) != '\0' && strBuilder.Length < 256) { strBuilder.Append(curChar); } texturePaths[i] = strBuilder.ToString(); strBuilder.Length = 0; } // Read MDLTextures string[] materialNames = new string[header.num_textures]; MDLTexture[] mdltexs = new MDLTexture[header.num_textures]; materials = new SourceMaterial[header.num_textures]; for (int i = 0; i < header.num_textures; i++) { // Seek to offset index int indexoffset = header.texture_offset + (i * 64); // MDLTexture is 64b MDLTexture mdltex = ReadMDLTexture(br, indexoffset); // Get material name br.BaseStream.Seek(indexoffset + mdltex.tex_name_offset, SeekOrigin.Begin); // Read name until \0 char is met char curChar; while ((curChar = br.ReadChar()) != '\0' && strBuilder.Length < 256) { strBuilder.Append(curChar); } mdltexs[i] = mdltex; materialNames[i] = strBuilder.ToString(); strBuilder.Length = 0; // Load material SourceMaterial material = TextureManager.Instance.LoadMaterial(materialNames[i]); materials[i] = material; } // Process the main models bodyparts for (int i = 0; i < header.num_body_parts; i++) { int offset = header.body_part_offset + (i * 16); // MDLBodyPart size = 16bytes BodyPart bp = ReadBodyPart(br, offset); srcModel.BodyParts.Add(bp); } // Read bones for (int i = 0; i < header.num_bones; i++) { int offset = header.bone_offset + (i * 216); mstudiobone_t bone = ReadBone(br, offset); } } // Read VVD (Vertex Data) datafile FCFile vvdFile = FileCache.Instance.GetFile(FCFile.GetFileName(file.FileName, false) + ".vvd"); if (vvdFile != null) { VVDReader.ReadFile(vvdFile.FullName); } // Read VTX (index & primitive data) file FCFile vtxFile = FileCache.Instance.GetFile(FCFile.GetFileName(file.FileName, false) + ".dx90.vtx"); if (vtxFile != null) { VTXReader.ReadFile(vtxFile.FullName, srcModel); } return true; }