Esempio n. 1
0
        private WMOGroupFile ReadWMOGroupFile(string filename, Stream wmo)
        {
            WMOGroupFile groupFile = new WMOGroupFile();

            var         bin = new BinaryReader(wmo);
            BlizzHeader chunk;

            long position = 0;

            while (position < wmo.Length)
            {
                wmo.Position = position;
                chunk        = new BlizzHeader(bin.ReadChars(4), bin.ReadUInt32());
                chunk.Flip();
                position = wmo.Position + chunk.Size;

                switch (chunk.ToString())
                {
                case "MVER":
                    groupFile.version = bin.Read <MVER>();
                    if (wmofile.version.version != 17)
                    {
                        throw new Exception("Unsupported WMO version! (" + wmofile.version.version + ")");
                    }
                    continue;

                case "MOGP":
                    groupFile.mogp = ReadMOGPChunk(chunk, bin);
                    continue;

                default:
                    throw new Exception(String.Format("{2} Found unknown header at offset {1} \"{0}\" while we should've already read them all!", chunk.ToString(), position.ToString(), filename));
                }
            }
            return(groupFile);
        }
Esempio n. 2
0
        /* GROUP */
        private WMOGroupFile ReadWMOGroupFile(uint filedataid, Stream wmo)
        {
            var groupFile = new WMOGroupFile();

            using (var bin = new BinaryReader(wmo))
            {
                long position = 0;
                while (position < wmo.Length)
                {
                    wmo.Position = position;
                    var chunkName = (WMOChunks)bin.ReadUInt32();
                    var chunkSize = bin.ReadUInt32();
                    position = wmo.Position + chunkSize;

                    switch (chunkName)
                    {
                    case WMOChunks.MVER:
                        groupFile.version = bin.ReadUInt32();
                        if (wmofile.version != 17)
                        {
                            throw new Exception("Unsupported WMO version! (" + wmofile.version + ")");
                        }
                        continue;

                    case WMOChunks.MOGP:
                        groupFile.mogp = ReadMOGPChunk(chunkSize, bin);
                        continue;

                    default:
                        throw new Exception(string.Format("{2} Found unknown header at offset {1} \"{0}\" while we should've already read them all!", chunkName.ToString("X"), position.ToString(), filedataid));
                    }
                }
            }

            return(groupFile);
        }
Esempio n. 3
0
        private void ReadWMO(string filename, Stream wmo)
        {
            var         bin = new BinaryReader(wmo);
            BlizzHeader chunk;

            long position = 0;

            while (position < wmo.Length)
            {
                wmo.Position = position;
                chunk        = new BlizzHeader(bin.ReadChars(4), bin.ReadUInt32());
                chunk.Flip();
                position = wmo.Position + chunk.Size;

                switch (chunk.ToString())
                {
                case "MVER":
                    wmofile.version = bin.Read <MVER>();
                    if (wmofile.version.version != 17)
                    {
                        throw new Exception("Unsupported WMO version! (" + wmofile.version.version + ") (" + filename + ")");
                    }
                    continue;

                case "MOTX":
                    wmofile.textures = ReadMOTXChunk(chunk, bin);
                    continue;

                case "MOHD":
                    wmofile.header = ReadMOHDChunk(chunk, bin, filename);
                    continue;

                case "MOGN":
                    wmofile.groupNames = ReadMOGNChunk(chunk, bin, wmofile.header.nGroups);
                    continue;

                case "MOGI":
                    wmofile.groupInfo = ReadMOGIChunk(chunk, bin, wmofile.header.nGroups);
                    continue;

                case "MOMT":
                    wmofile.materials = ReadMOMTChunk(chunk, bin, wmofile.header.nMaterials);
                    continue;

                case "MODN":
                    wmofile.doodadNames = ReadMODNChunk(chunk, bin, wmofile.header.nModels);
                    continue;

                case "MODD":
                    wmofile.doodadDefinitions = ReadMODDChunk(chunk, bin);
                    continue;

                case "MOGP":
                //ReadMOGPChunk(chunk, bin);
                //continue;
                case "MOSB":
                case "MOPV":
                case "MOPT":
                case "MOPR":
                case "MOVV":     //Visible block vertices
                case "MOVB":     //Visible block list
                case "MOLT":
                case "MODS":

                case "MFOG":
                case "MCVP":
                case "GFID":     // Legion
                    continue;

                default:
                    throw new Exception(String.Format("{2} Found unknown header at offset {1} \"{0}\" while we should've already read them all!", chunk.ToString(), position.ToString(), filename));
                }
            }
            //open group files
            WMOGroupFile[] groupFiles = new WMOGroupFile[wmofile.header.nGroups];
            for (int i = 0; i < wmofile.header.nGroups; i++)
            {
                string groupfilename = groupfilename = filename.Replace(".wmo", "_" + i.ToString().PadLeft(3, '0') + ".wmo");

                if (_lod)
                {
                    if (CASC.FileExists(groupfilename.Replace(".wmo", "_lod2.wmo")))
                    {
                        groupfilename = groupfilename.Replace(".wmo", "_lod2.wmo");
                        Console.WriteLine("[LOD] Loading LOD 2 for group " + i);
                    }
                    else if (CASC.FileExists(groupfilename.Replace(".wmo", "_lod1.wmo")))
                    {
                        groupfilename = groupfilename.Replace(".wmo", "_lod1.wmo");
                        Console.WriteLine("[LOD] Loading LOD 1 for group " + i);
                    }
                    else
                    {
                        Console.WriteLine("[LOD] No LOD " + i);
                    }
                }

                if (!CASC.FileExists(groupfilename))
                {
                    new WoWFormatLib.Utils.MissingFile(groupfilename);
                    return;
                }
                else
                {
                    using (Stream wmoStream = CASC.OpenFile(groupfilename))
                    {
                        groupFiles[i] = ReadWMOGroupFile(groupfilename, wmoStream);
                    }
                }
            }

            wmofile.group = groupFiles;
        }
Esempio n. 4
0
        /* PARENT */
        private void ReadWMO(string filename, Stream wmo)
        {
            using (var bin = new BinaryReader(wmo))
            {
                long position = 0;
                while (position < wmo.Length)
                {
                    wmo.Position = position;

                    var chunkName = new string(bin.ReadChars(4).Reverse().ToArray());
                    var chunkSize = bin.ReadUInt32();

                    position = wmo.Position + chunkSize;

                    switch (chunkName)
                    {
                    case "MVER":
                        wmofile.version = bin.Read <MVER>();
                        if (wmofile.version.version != 17)
                        {
                            throw new Exception("Unsupported WMO version! (" + wmofile.version.version + ") (" + filename + ")");
                        }
                        break;

                    case "MOHD":
                        wmofile.header = ReadMOHDChunk(bin, filename);
                        break;

                    case "MOTX":
                        wmofile.textures = ReadMOTXChunk(chunkSize, bin);
                        break;

                    case "MOMT":
                        wmofile.materials = ReadMOMTChunk(bin, wmofile.header.nMaterials);
                        break;

                    case "MOGN":
                        wmofile.groupNames = ReadMOGNChunk(chunkSize, bin, wmofile.header.nGroups);
                        break;

                    case "MOGI":
                        wmofile.groupInfo = ReadMOGIChunk(bin, wmofile.header.nGroups);
                        break;

                    case "MODS":
                        wmofile.doodadSets = ReadMODSChunk(chunkSize, bin);
                        break;

                    case "MODN":
                        wmofile.doodadNames = ReadMODNChunk(chunkSize, bin, wmofile.header.nModels);
                        break;

                    case "MODD":
                        wmofile.doodadDefinitions = ReadMODDChunk(chunkSize, bin);
                        break;

                    case "MOSB":     // Skybox
                    case "MOPV":     // Portal Vertices
                    case "MOPR":     // Portal References
                    case "MOPT":     // Portal Information
                    case "MOVV":     // Visible block vertices
                    case "MOVB":     // Visible block list
                    case "MOLT":     // Lighting Infroamtion
                    case "MFOG":     // Fog Information
                    case "MCVP":     // Convex Volume Planes
                    case "MOUV":     // 7.3 - ?
                    case "GFID":     // Legion
                        break;

                    default:
                        throw new Exception(String.Format("{2} Found unknown header at offset {1} \"{0}\" while we should've already read them all!", chunkName, position.ToString(), filename));
                    }
                }
            }

            WMOGroupFile[] groupFiles = new WMOGroupFile[wmofile.header.nGroups];
            for (int i = 0; i < wmofile.header.nGroups; i++)
            {
                string groupfilename = filename.ToLower().Replace(".wmo", "_" + i.ToString().PadLeft(3, '0') + ".wmo");

                if (_lod)
                {
                    if (CASC.cascHandler.FileExists(groupfilename.Replace(".wmo", "_lod2.wmo")))
                    {
                        groupfilename = groupfilename.Replace(".wmo", "_lod2.wmo");
                        Console.WriteLine("[LOD] Loading LOD 2 for group " + i);
                    }
                    else if (CASC.cascHandler.FileExists(groupfilename.Replace(".wmo", "_lod1.wmo")))
                    {
                        groupfilename = groupfilename.Replace(".wmo", "_lod1.wmo");
                        Console.WriteLine("[LOD] Loading LOD 1 for group " + i);
                    }
                    else
                    {
                        Console.WriteLine("[LOD] No LOD " + i);
                    }
                }

                if (CASC.cascHandler.FileExists(groupfilename))
                {
                    using (Stream wmoStream = CASC.cascHandler.OpenFile(groupfilename))
                    {
                        groupFiles[i] = ReadWMOGroupFile(groupfilename, wmoStream);
                    }
                }
            }

            wmofile.group = groupFiles;
        }
Esempio n. 5
0
        /* PARENT */
        private void ReadWMO(Stream wmo, string filename = "")
        {
            using (var bin = new BinaryReader(wmo))
            {
                long position = 0;
                while (position < wmo.Length)
                {
                    wmo.Position = position;

                    var chunkName = (WMOChunks)bin.ReadUInt32();
                    var chunkSize = bin.ReadUInt32();

                    position = wmo.Position + chunkSize;

                    switch (chunkName)
                    {
                    case WMOChunks.MVER:
                        wmofile.version = bin.ReadUInt32();
                        if (wmofile.version != 17)
                        {
                            throw new Exception("Unsupported WMO version! (" + wmofile.version + ")");
                        }
                        break;

                    case WMOChunks.MOGP:
                        throw new NotSupportedException("Trying to parse group WMO as root WMO!");

                    case WMOChunks.MOHD:
                        wmofile.header = bin.Read <MOHD>();
                        break;

                    case WMOChunks.MOTX:
                        wmofile.textures = ReadMOTXChunk(chunkSize, bin);
                        break;

                    case WMOChunks.MOMT:
                        wmofile.materials = ReadMOMTChunk(chunkSize, bin);
                        break;

                    case WMOChunks.MOGN:
                        wmofile.groupNames = ReadMOGNChunk(chunkSize, bin);
                        break;

                    case WMOChunks.MOGI:
                        wmofile.groupInfo = ReadMOGIChunk(chunkSize, bin);
                        break;

                    case WMOChunks.MODS:
                        wmofile.doodadSets = ReadMODSChunk(chunkSize, bin);
                        break;

                    case WMOChunks.MODI:
                        wmofile.doodadIds = ReadMODIChunk(chunkSize, bin);
                        break;

                    case WMOChunks.MODN:
                        wmofile.doodadNames = ReadMODNChunk(chunkSize, bin);
                        break;

                    case WMOChunks.MODD:
                        wmofile.doodadDefinitions = ReadMODDChunk(chunkSize, bin);
                        break;

                    case WMOChunks.MOSB:
                        wmofile.skybox = ReadMOSBChunk(chunkSize, bin);
                        break;

                    case WMOChunks.MOSI:
                        wmofile.skyboxFileDataID = ReadMOSIChunk(chunkSize, bin);
                        break;

                    case WMOChunks.GFID:
                        wmofile.groupFileDataIDs = ReadGFIDChunk(chunkSize, bin);
                        break;

                    case WMOChunks.MOPV:     // MOPV Portal Vertices
                    case WMOChunks.MOPR:     // MOPR Portal References
                    case WMOChunks.MOPT:     // MOPT Portal Information
                    case WMOChunks.MOVV:     // MOVV Visible block vertices
                    case WMOChunks.MOVB:     // MOVB Visible block list
                    case WMOChunks.MOLT:     // MOLT Lighting Information
                    case WMOChunks.MFOG:     // MFOG Fog Information
                    case WMOChunks.MCVP:     // MCVP Convex Volume Planes
                    case WMOChunks.MOUV:     // MOUV Animated texture UVs
                    case WMOChunks.MLSP:     // ?
                    case WMOChunks.MDDI:     // ?
                        break;

                    default:
                        Console.WriteLine(string.Format("Found unknown header at offset {1} \"{0}\" while we should've already read them all!", chunkName.ToString("X"), position.ToString()));
                        break;
                    }
                }
            }

            var groupFiles = new WMOGroupFile[wmofile.header.nGroups];

            if (wmofile.header.nLod != 0 && (lodLevel + 1) > wmofile.header.nLod)
            {
                throw new Exception("Requested LOD (" + lodLevel + ") exceeds the max LOD for this WMO (" + (wmofile.header.nLod - 1) + ")");
            }

            var start = wmofile.header.nGroups * lodLevel;

            if (wmofile.groupFileDataIDs == null && !string.IsNullOrEmpty(filename))
            {
                for (var i = 0; i < wmofile.header.nGroups; i++)
                {
                    var groupFilename = filename.Replace(".wmo", "_" + i.ToString().PadLeft(3, '0') + ".wmo");
                    if (CASC.IsCASCInit && CASC.FileExists(groupFilename))
                    {
                        var groupFileDataID = CASC.getFileDataIdByName(groupFilename);
                        using (var wmoStream = CASC.OpenFile(groupFileDataID))
                        {
                            groupFiles[i] = ReadWMOGroupFile(groupFileDataID, wmoStream);
                        }
                    }
                    else
                    {
                        Console.WriteLine("CASC is reporting " + groupFilename + " does not exist!");
                    }
                }
            }
            else
            {
                for (var i = 0; i < wmofile.header.nGroups; i++)
                {
                    var groupFileDataID = wmofile.groupFileDataIDs[start + i];

                    if (lodLevel == 3 && groupFileDataID == 0) // if lod is 3 and there's no lod3 available, fall back to lod1
                    {
                        groupFileDataID = wmofile.groupFileDataIDs[i + (wmofile.header.nGroups * 2)];
                    }

                    if (lodLevel >= 2 && groupFileDataID == 0) // if lod is 2 or higher and there's no lod2 available, fall back to lod1
                    {
                        groupFileDataID = wmofile.groupFileDataIDs[i + (wmofile.header.nGroups * 1)];
                    }

                    if (lodLevel >= 1 && groupFileDataID == 0) // if lod is 1 or higher check if lod1 available, fall back to lod0
                    {
                        groupFileDataID = wmofile.groupFileDataIDs[i];
                    }

                    if (CASC.IsCASCInit && CASC.FileExists(groupFileDataID))
                    {
                        using (var wmoStream = CASC.OpenFile(groupFileDataID))
                        {
                            groupFiles[i] = ReadWMOGroupFile(groupFileDataID, wmoStream);
                        }
                    }
                    else
                    {
                        //Console.WriteLine("CASC is reporting " + groupFileDataID + " does not exist! This shouldn't happen.");
                    }
                }
            }

            wmofile.group = groupFiles;
        }