Example #1
0
        public WMOGroup(string filename)
        {
            Filename = filename;

            var mainChunk = new ChunkData(filename);

            MOGP = new MOGP(Chunk = mainChunk.GetChunkByName("MOGP"));

            var stream = Chunk.GetStream();

            stream.Seek(Chunk.Offset + MOGP.ChunkHeaderSize, SeekOrigin.Begin);
            SubData = new ChunkData(stream, Chunk.Size - MOGP.ChunkHeaderSize);

            Read();
        }
Example #2
0
        public MOGP ReadMOGPChunk(BlizzHeader chunk, BinaryReader bin)
        {
            MOGP mogp = new MOGP();

            mogp.nameOffset            = bin.ReadUInt32();
            mogp.descriptiveNameOffset = bin.ReadUInt32();
            mogp.flags        = (MOGPFlags)bin.ReadUInt32();
            mogp.boundingBox1 = bin.Read <Vector3>();
            mogp.boundingBox2 = bin.Read <Vector3>();
            mogp.ofsPortals   = bin.ReadUInt16();
            mogp.numPortals   = bin.ReadUInt16();
            mogp.numBatchesA  = bin.ReadUInt16();
            mogp.numBatchesB  = bin.ReadUInt16();
            mogp.numBatchesC  = bin.ReadUInt32();
            //mogp.fogIndices = bin.ReadBytes(4);
            bin.ReadBytes(4);
            mogp.liquidType = bin.ReadUInt32();
            mogp.groupID    = bin.ReadUInt32();
            mogp.unk0       = bin.ReadUInt32();
            mogp.unk1       = bin.ReadUInt32();
            MemoryStream stream = new MemoryStream(bin.ReadBytes((int)chunk.Size));
            var          subbin = new BinaryReader(stream);
            BlizzHeader  subchunk;
            long         position = 0;
            int          MOTVi    = 0;

            if (mogp.flags.HasFlag(MOGPFlags.Flag_0x40000000))
            {
                mogp.textureCoords = new MOTV[3][];
            }
            else
            {
                mogp.textureCoords = new MOTV[2][];
            }


            while (position < stream.Length)
            {
                stream.Position = position;
                subchunk        = new BlizzHeader(subbin.ReadChars(4), subbin.ReadUInt32());
                subchunk.Flip();
                position = stream.Position + subchunk.Size;
                //Console.WriteLine(subchunk.ToString());
                switch (subchunk.ToString())
                {
                case "MOVI":     //Vertex indices for triangles
                    mogp.indices = ReadMOVIChunk(subchunk, subbin);
                    //Console.WriteLine("Read " + mogp.indices.Length + " indices!");
                    break;

                case "MOVT":     //Vertices chunk
                    mogp.vertices = ReadMOVTChunk(subchunk, subbin);
                    break;

                case "MOTV":     //Texture coordinates
                    mogp.textureCoords[MOTVi++] = ReadMOTVChunk(subchunk, subbin);
                    break;

                case "MONR":     //Normals
                    mogp.normals = ReadMONRChunk(subchunk, subbin);
                    break;

                case "MOBA":     //Render batches
                    mogp.renderBatches = ReadMOBAChunk(subchunk, subbin);
                    break;

                case "MOPY":     //Material info for triangles, two bytes per triangle.
                    mogp.materialInfo = ReadMOPYChunk(subchunk, subbin);
                    break;

                case "MOBS":     //Unk
                case "MODR":     //Doodad references
                case "MOBN":     //Array of t_BSP_NODE
                case "MOBR":     //Face indices
                case "MOLR":     //Light references
                case "MOCV":     //Vertex colors
                case "MDAL":     //Unk (new in WoD?)
                case "MLIQ":     //Liquids
                case "MOTA":     //Unknown
                case "MOPL":     //Unknown
                case "MOLP":     //Unknown
                    continue;

                default:
                    throw new Exception(String.Format("Found unknown header at offset {1} \"{0}\" while we should've already read them all!", subchunk.ToString(), position.ToString()));
                }
            }
            //if(MOTVi == 0) { throw new Exception("Didn't parse any MOTV??");  } // antiportal groups have no motv
            return(mogp);
        }
Example #3
0
        private MOGP ReadMOGPChunk(uint size, BinaryReader bin)
        {
            MOGP mogp = new MOGP()
            {
                nameOffset            = bin.ReadUInt32(),
                descriptiveNameOffset = bin.ReadUInt32(),
                flags        = (MOGPFlags)bin.ReadUInt32(),
                boundingBox1 = bin.Read <Vector3>(),
                boundingBox2 = bin.Read <Vector3>(),
                ofsPortals   = bin.ReadUInt16(),
                numPortals   = bin.ReadUInt16(),
                numBatchesA  = bin.ReadUInt16(),
                numBatchesB  = bin.ReadUInt16(),
                numBatchesC  = bin.ReadUInt32(),
                unused       = bin.ReadUInt32(),
                liquidType   = bin.ReadUInt32(),
                groupID      = bin.ReadUInt32(),
                unk0         = bin.ReadUInt32(),
                unk1         = bin.ReadUInt32()
            };

            using (var stream = new MemoryStream(bin.ReadBytes((int)size)))
                using (var subbin = new BinaryReader(stream))
                {
                    long position = 0;
                    int  MOTVi    = 0;

                    if (mogp.flags.HasFlag(MOGPFlags.Flag_0x40000000))
                    {
                        mogp.textureCoords = new MOTV[3][];
                    }
                    else
                    {
                        mogp.textureCoords = new MOTV[2][];
                    }

                    while (position < stream.Length)
                    {
                        stream.Position = position;

                        var subChunkName = new string(subbin.ReadChars(4).Reverse().ToArray());
                        var subChunkSize = subbin.ReadUInt32();

                        position = stream.Position + subChunkSize;

                        switch (subChunkName)
                        {
                        case "MOVI": //Vertex indices for triangles
                            mogp.indices = ReadMOVIChunk(subChunkSize, subbin);
                            //Console.WriteLine("Read " + mogp.indices.Length + " indices!");
                            break;

                        case "MOVT": //Vertices chunk
                            mogp.vertices = ReadMOVTChunk(subChunkSize, subbin);
                            break;

                        case "MOTV": //Texture coordinates
                            mogp.textureCoords[MOTVi++] = ReadMOTVChunk(subChunkSize, subbin);
                            break;

                        case "MONR": //Normals
                            mogp.normals = ReadMONRChunk(subChunkSize, subbin);
                            break;

                        case "MOBA": //Render batches
                            mogp.renderBatches = ReadMOBAChunk(subChunkSize, subbin);
                            break;

                        case "MOPY": //Material info for triangles, two bytes per triangle.
                            mogp.materialInfo = ReadMOPYChunk(subChunkSize, subbin);
                            break;

                        case "MOBS": //Unk
                        case "MODR": //Doodad references
                        case "MOBN": //Array of t_BSP_NODE
                        case "MOBR": //Face indices
                        case "MOLR": //Light references
                        case "MOCV": //Vertex colors
                        case "MDAL": //Unk (new in WoD?)
                        case "MLIQ": //Liquids
                        case "MOTA": //Unknown
                        case "MOPL": //Unknown
                        case "MOLP": //Unknown
                        case "MOLS": //Unknown
                            continue;

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

            return(mogp);
        }
Example #4
0
        private MOGP ReadMOGPChunk(uint size, BinaryReader bin)
        {
            var mogp = new MOGP()
            {
                nameOffset            = bin.ReadUInt32(),
                descriptiveNameOffset = bin.ReadUInt32(),
                flags        = (MOGPFlags)bin.ReadUInt32(),
                boundingBox1 = bin.Read <Vector3>(),
                boundingBox2 = bin.Read <Vector3>(),
                ofsPortals   = bin.ReadUInt16(),
                numPortals   = bin.ReadUInt16(),
                numBatchesA  = bin.ReadUInt16(),
                numBatchesB  = bin.ReadUInt16(),
                numBatchesC  = bin.ReadUInt32(),
                unused       = bin.ReadUInt32(),
                liquidType   = bin.ReadUInt32(),
                groupID      = bin.ReadUInt32(),
                unk0         = bin.ReadUInt32(),
                unk1         = bin.ReadUInt32()
            };

            using (var stream = new MemoryStream(bin.ReadBytes((int)size)))
                using (var subbin = new BinaryReader(stream))
                {
                    long position = 0;
                    var  MOTVi    = 0;

                    if (mogp.flags.HasFlag(MOGPFlags.Flag_0x40000000))
                    {
                        mogp.textureCoords = new MOTV[3][];
                    }
                    else
                    {
                        mogp.textureCoords = new MOTV[2][];
                    }

                    while (position < stream.Length)
                    {
                        stream.Position = position;

                        var subChunkName = (WMOChunks)subbin.ReadUInt32();
                        var subChunkSize = subbin.ReadUInt32();

                        position = stream.Position + subChunkSize;

                        switch (subChunkName)
                        {
                        case WMOChunks.MOVI: // MOVI Vertex indices for triangles
                            mogp.indices = ReadMOVIChunk(subChunkSize, subbin);
                            break;

                        case WMOChunks.MOVT: // MOVT Vertices chunk
                            mogp.vertices = ReadMOVTChunk(subChunkSize, subbin);
                            break;

                        case WMOChunks.MOTV: // MOTV Texture coordinates
                            mogp.textureCoords[MOTVi++] = ReadMOTVChunk(subChunkSize, subbin);
                            break;

                        case WMOChunks.MONR: // MONR Normals
                            mogp.normals = ReadMONRChunk(subChunkSize, subbin);
                            break;

                        case WMOChunks.MOBA: // MOBA Render batches
                            mogp.renderBatches = ReadMOBAChunk(subChunkSize, subbin);
                            break;

                        case WMOChunks.MOPY: // MOPY Material info for triangles, two bytes per triangle.
                            mogp.materialInfo = ReadMOPYChunk(subChunkSize, subbin);
                            break;

                        case WMOChunks.MOBS: // MOBS Unk
                        case WMOChunks.MODR: // MODR Doodad references
                        case WMOChunks.MOBN: // MOBN Array of t_BSP_NODE
                        case WMOChunks.MOBR: // MOBR Face indices
                        case WMOChunks.MOLR: // MOLR Light references
                        case WMOChunks.MOCV: // MOCV Vertex colors
                        case WMOChunks.MDAL: // MDAL Unk (new in WoD)
                        case WMOChunks.MLIQ: // MLIQ Liquids
                        case WMOChunks.MOTA: // MOTA Tangent Array
                        case WMOChunks.MOPL: // MOPL Terrain Cutting PLanes
                        case WMOChunks.MOLP: // MOLP Points Lights
                        case WMOChunks.MOLS: // MOLS Spot Lights
                        case WMOChunks.MOPB: // MOPB Prepass Batches
                        case WMOChunks.MLSP: // ?
                        case WMOChunks.MLSS: // ?
                        case WMOChunks.MLSK: // ?
                        case WMOChunks.MOP2: // ?
                            continue;

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

            return(mogp);
        }