static void ReadMOLT(BinaryReader br, WMORoot wmo)
        {
            wmo.LightInfo = new LightInformation[wmo.Header.LightCount];

            for (int i = 0; i < wmo.LightInfo.Length; i++)
            {
                var light = new LightInformation
                {
                    Byte_1     = br.ReadByte(),
                    Byte_2     = br.ReadByte(),
                    Byte_3     = br.ReadByte(),
                    Byte_4     = br.ReadByte(),
                    Color      = br.ReadColor4(),
                    Position   = br.ReadVector3(),
                    Intensity  = br.ReadSingle(),
                    AttenStart = br.ReadSingle(),
                    AttenEnd   = br.ReadSingle(),
                    Float_4    = br.ReadSingle(),
                    Float_5    = br.ReadSingle(),
                    Float_6    = br.ReadSingle(),
                    Float_7    = br.ReadSingle()
                };

                //FixVector3(ref light.position);

                wmo.LightInfo[i] = light;
            }
        }
        static void ReadMODD(BinaryReader br, WMORoot wmo, uint size)
        {
            // Why oh why is wmo.Header.DoodadCount wrong sometimes
            // 40 is the size of DoodadDefinition
            wmo.DoodadDefinitions = new DoodadDefinition[size / 40];

            for (var i = 0; i < wmo.DoodadDefinitions.Length; i++)
            {
                var dd = new DoodadDefinition
                {
                    NameIndex = br.ReadInt32(),
                    Position  = br.ReadVector3(),
                    Rotation  = br.ReadQuaternion(),
                    Scale     = br.ReadSingle(),
                    Color     = br.ReadColor4()
                };

                if (dd.NameIndex != -1)
                {
                    if (!wmo.DoodadFiles.TryGetValue(dd.NameIndex, out dd.FilePath))
                    {
                        dd.FilePath = "";
                        log.Error(String.Format("Doodad File Path for index: {0} missing from the Dictionary!", dd.NameIndex));
                    }
                }

                wmo.DoodadDefinitions[i] = dd;
            }
        }
        static void ReadMFOG(BinaryReader br, WMORoot wmo, uint size)
        {
            wmo.Fogs = new Fog[size / 48];

            for (int i = 0; i < wmo.Fogs.Length; i++)
            {
                var fog = new Fog
                {
                    Flags       = (FogFlags)br.ReadUInt32(),
                    Position    = br.ReadVector3(),
                    Start       = br.ReadSingle(),
                    End         = br.ReadSingle(),
                    FogInfo_FOG = new FogInfo
                    {
                        End         = br.ReadSingle(),
                        StartScalar = br.ReadSingle(),
                        Color       = br.ReadColor4()
                    },
                    FogInfo_UWFOG = new FogInfo
                    {
                        End         = br.ReadSingle(),
                        StartScalar = br.ReadSingle(),
                        Color       = br.ReadColor4()
                    }
                };

                wmo.Fogs[i] = fog;
            }
        }
        static void ReadMOMT(BinaryReader br, WMORoot wmo)
        {
            wmo.Materials = new Material[wmo.Header.TextureCount];

            for (int i = 0; i < wmo.Materials.Length; i++)
            {
                var mt = new Material
                {
                    Flags            = (MaterialFlags)br.ReadUInt32(),
                    Int_1            = br.ReadUInt32(),
                    BlendMode        = br.ReadInt32(),
                    TextureNameStart = br.ReadInt32(),
                    SidnColor        = br.ReadColor4(),
                    FrameSidnColor   = br.ReadColor4(),
                    TextureNameEnd   = br.ReadInt32(),
                    DiffColor        = br.ReadColor4(),
                    GroundType       = br.ReadInt32(),
                    Float_1          = br.ReadSingle(),
                    Float_2          = br.ReadSingle(),
                    Int_2            = br.ReadInt32(),
                    Int_3            = br.ReadInt32(),
                    Int_4            = br.ReadInt32()
                };

                // these 2 are set in RAM in the client to the associated HTEXTUREs
                br.ReadUInt32(); // 0x38
                br.ReadUInt32(); // 0x3C

                wmo.Materials[i] = mt;

                //if (mt.Flags != 0)
                //Console.WriteLine();
            }
        }
        static void ReadMOVV(BinaryReader br, WMORoot wmo, uint size)
        {
            wmo.VisibleVertices = new Vector3[size / 12]; // 12 = sizeof(Vector3), but we can't use sizeof with Vector3

            for (int i = 0; i < wmo.VisibleVertices.Length; i++)
            {
                wmo.VisibleVertices[i] = br.ReadVector3();
            }
        }
        static void ReadMCVP(BinaryReader br, WMORoot wmo, uint size)
        {
            wmo.ComplexVolumePlanes = new Plane[size / (4 * sizeof(float))];

            for (int i = 0; i < wmo.ComplexVolumePlanes.Length; i++)
            {
                wmo.ComplexVolumePlanes[i] = br.ReadPlane();
            }
        }
Exemple #7
0
        public WMOHolder(WMORoot wmo)
        {
            WMO = wmo;

            var min = wmo.Bounds.Min;
            var max = wmo.Bounds.Max;
            var minPoint = new Point(min.X, min.Y);
            var maxPoint = new Point(max.X, max.Y);
            Bounds = new Rect(minPoint, maxPoint);
        }
        static void ReadMOPV(BinaryReader br, WMORoot wmo)
        {
            // PortalCount of 4 x Vector3 to form a rectangle for the doorway
            uint vertexCount = wmo.Header.PortalCount * 4;

            wmo.PortalVertices = new Vector3[vertexCount];

            for (var i = 0; i < vertexCount; i++)
            {
                wmo.PortalVertices[i] = br.ReadVector3();
            }
        }
        static void ReadMOVB(BinaryReader br, WMORoot wmo, uint size)
        {
            uint blockCount = size / 4;

            wmo.VisibleBlocks = new VertexSpan[blockCount];

            for (int i = 0; i < blockCount; i++)
            {
                wmo.VisibleBlocks[i] = new VertexSpan
                {
                    StartVertex = br.ReadInt16(),
                    VertexCount = br.ReadInt16()
                };
            }
        }
Exemple #10
0
        static void ReadMOGI(BinaryReader br, WMORoot wmo)
        {
            wmo.GroupInformation = new GroupInformation[wmo.Header.GroupCount];

            for (int i = 0; i < wmo.GroupInformation.Length; i++)
            {
                var g = new GroupInformation {
                    Flags       = (WMOGroupFlags)br.ReadUInt32(),
                    BoundingBox = new BoundingBox(br.ReadWMOVector3(), br.ReadWMOVector3()),
                    NameIndex   = br.ReadInt32()
                };

                wmo.GroupInformation[i] = g;
            }
        }
Exemple #11
0
        static void ReadMOPR(BinaryReader br, WMORoot wmo)
        {
            wmo.PortalRelations = new PortalRelation[wmo.Header.PortalCount];

            for (int i = 0; i < wmo.PortalRelations.Length; i++)
            {
                var r = new PortalRelation
                {
                    PortalIndex = br.ReadUInt16(),
                    GroupIndex  = br.ReadUInt16(),
                    Side        = br.ReadInt16()
                };
                br.ReadInt16(); // filler

                wmo.PortalRelations[i] = r;
            }
        }
Exemple #12
0
        static void ReadMODS(BinaryReader br, WMORoot wmo)
        {
            wmo.DoodadSets = new DoodadSet[wmo.Header.DoodadSetCount];

            for (int i = 0; i < wmo.Header.DoodadSetCount; i++)
            {
                var d = new DoodadSet
                {
                    SetName            = br.ReadFixedString(20),
                    FirstInstanceIndex = br.ReadUInt32(),
                    InstanceCount      = br.ReadUInt32()
                };
                br.ReadInt32(); // padding

                wmo.DoodadSets[i] = d;
            }
        }
Exemple #13
0
        static void ReadMOGN(BinaryReader br, WMORoot wmo, uint size)
        {
            wmo.GroupNames = new Dictionary <int, string>();

            long endPos = br.BaseStream.Position + size;

            while (br.BaseStream.Position < endPos)
            {
                if (br.PeekByte() == 0)
                {
                    br.BaseStream.Position++;
                }
                else
                {
                    wmo.GroupNames.Add((int)(size - (endPos - br.BaseStream.Position)), br.ReadCString());
                }
            }
        }
Exemple #14
0
        /// <summary>
        /// Gets a WMOGroup from the WMO Group file
        /// </summary>
        /// <param name="manager"></param>
        /// <param name="filePath">File path to the WMOGroup</param>
        /// <param name="root"></param>
        /// <param name="groupIndex">Current index in the WMO Group</param>
        /// <returns>A WMOGroup from the WMO Group file</returns>
        public static WMOGroup Process(MpqManager manager, string filePath, WMORoot root, int groupIndex)
        {
            if (!manager.FileExists(filePath))
            {
                log.Error("WMOGroup file does not exist: ", filePath);
            }

            var currentWMOGroup = new WMOGroup(root, groupIndex);

            using (var stream = manager.OpenFile(filePath))
            using (var br = new BinaryReader(stream))
            {
                ReadRequiredChunks(br, currentWMOGroup);
                ReadOptionalChunks(br, currentWMOGroup);
            }

            return currentWMOGroup;
        }
Exemple #15
0
        /// <summary>
        /// Gets a WMOGroup from the WMO Group file
        /// </summary>
        /// <param name="manager"></param>
        /// <param name="filePath">File path to the WMOGroup</param>
        /// <param name="root"></param>
        /// <param name="groupIndex">Current index in the WMO Group</param>
        /// <returns>A WMOGroup from the WMO Group file</returns>
        public static WMOGroup Process(MpqManager manager, string filePath, WMORoot root, int groupIndex)
        {
            if (!manager.FileExists(filePath))
            {
                log.Error("WMOGroup file does not exist: ", filePath);
            }

            var currentWMOGroup = new WMOGroup(root, groupIndex);

            using (var stream = manager.OpenFile(filePath))
                using (var br = new BinaryReader(stream))
                {
                    ReadRequiredChunks(br, currentWMOGroup);
                    ReadOptionalChunks(br, currentWMOGroup);
                }

            return(currentWMOGroup);
        }
Exemple #16
0
        static void ReadMOPT(BinaryReader br, WMORoot wmo)
        {
            wmo.PortalInformation = new PortalInformation[wmo.Header.PortalCount];

            for (var i = 0; i < wmo.Header.PortalCount; i++)
            {
                var p = new PortalInformation
                {
                    Vertices = new VertexSpan
                    {
                        StartVertex = br.ReadInt16(),
                        VertexCount = br.ReadInt16(),
                    },
                    Plane = br.ReadPlane()
                };
                wmo.PortalInformation[i] = p;
            }
        }
Exemple #17
0
        /// <summary>
        /// Reads the header for the root file
        /// </summary>
        static void ReadMOHD(BinaryReader br, WMORoot wmo)
        {
            wmo.Header.TextureCount   = br.ReadUInt32();
            wmo.Header.GroupCount     = br.ReadUInt32();
            wmo.Header.PortalCount    = br.ReadUInt32();
            wmo.Header.LightCount     = br.ReadUInt32();
            wmo.Header.ModelCount     = br.ReadUInt32();
            wmo.Header.DoodadCount    = br.ReadUInt32();
            wmo.Header.DoodadSetCount = br.ReadUInt32();

            wmo.Header.AmbientColor = br.ReadColor4();
            wmo.Header.WMOId        = br.ReadUInt32();

            wmo.Header.BoundingBox = new BoundingBox(br.ReadWMOVector3(), br.ReadWMOVector3());

            wmo.Header.Flags = (WMORootHeaderFlags)br.ReadUInt32();

            wmo.Groups = new WMOGroup[wmo.Header.GroupCount];
        }
        private static void WriteDoodadDefinitions(BinaryWriter writer, WMORoot root)
        {
            var doodadSets = new List<List<int>>();
            foreach(var set in root.DoodadSets)
            {
                var list = new List<int>((int)set.InstanceCount);
                for (var i = 0; i < set.InstanceCount; i++)
                {
                    var idx = set.FirstInstanceIndex + i;
                    var def = root.DoodadDefinitions[idx];
                    if (def == null) continue;
                    if (TileExtractor.ModelsToIgnore.Contains(def.FilePath)) continue;

                    list.Add((int)idx);
                }

                doodadSets.Add(list);
            }

            writer.Write(doodadSets.Count);
            foreach (var doodadSet in doodadSets)
            {
                writer.Write(doodadSet.Count);
                foreach (var defId in doodadSet)
                {
                    var def = root.DoodadDefinitions[defId];

                    writer.Write(defId);
                    writer.Write(def.FilePath);
                    writer.Write(def.Position);
                    writer.Write(def.Extents);
                    writer.Write(def.WMOToModel);
                    writer.Write(def.ModelToWMO);
                }
            }
        }
 private static void ExtractWMOM2s(WMORoot root)
 {
     foreach (var def in root.DoodadDefinitions)
     {
         ExtractM2Model(def.FilePath);
     }
 }
Exemple #20
0
        static void ReadMFOG(BinaryReader br, WMORoot wmo, uint size)
        {
            wmo.Fogs = new Fog[size/48];

            for (int i = 0; i < wmo.Fogs.Length; i++)
            {
                var fog = new Fog
                              {
                                  Flags = (FogFlags)br.ReadUInt32(),
                                  Position = br.ReadVector3(),
                                  Start = br.ReadSingle(),
                                  End = br.ReadSingle(),
                                  FogInfo_FOG = new FogInfo
                                                 {
                                                     End = br.ReadSingle(),
                                                     StartScalar = br.ReadSingle(),
                                                     Color = br.ReadColor4()
                                                 },
                                  FogInfo_UWFOG = new FogInfo
                                                 {
                                                     End = br.ReadSingle(),
                                                     StartScalar = br.ReadSingle(),
                                                     Color = br.ReadColor4()
                                                 }
                              };

                wmo.Fogs[i] = fog;
            }
        }
Exemple #21
0
        static void ReadMODS(BinaryReader br, WMORoot wmo)
        {
            wmo.DoodadSets = new DoodadSet[wmo.Header.DoodadSetCount];

            for (int i = 0; i < wmo.Header.DoodadSetCount; i++)
            {
                var d = new DoodadSet
                {
                    SetName = br.ReadFixedString(20),
                    FirstInstanceIndex = br.ReadUInt32(),
                    InstanceCount = br.ReadUInt32()
                };
                br.ReadInt32(); // padding

                wmo.DoodadSets[i] = d;
            }
        }
Exemple #22
0
        /// <summary>
        /// Reads the header for the root file
        /// </summary>
        static void ReadMOHD(BinaryReader br, WMORoot wmo)
        {
            wmo.Header.TextureCount = br.ReadUInt32();
            wmo.Header.GroupCount = br.ReadUInt32();
            wmo.Header.PortalCount = br.ReadUInt32();
            wmo.Header.LightCount = br.ReadUInt32();
            wmo.Header.ModelCount = br.ReadUInt32();
            wmo.Header.DoodadCount = br.ReadUInt32();
            wmo.Header.DoodadSetCount = br.ReadUInt32();

            wmo.Header.AmbientColor = br.ReadColor4();
            wmo.Header.WMOId = br.ReadUInt32();

            wmo.Header.BoundingBox = new BoundingBox(br.ReadWMOVector3(), br.ReadWMOVector3());

            wmo.Header.Flags = (WMORootHeaderFlags)br.ReadUInt32();

            wmo.Groups = new WMOGroup[wmo.Header.GroupCount];
        }
Exemple #23
0
 static void ReadMVER(BinaryReader br, WMORoot wmo)
 {
     wmo.Version = br.ReadInt32();
 }
Exemple #24
0
        public static WMORoot Process(MpqManager mpqManager, string filePath)
        {
            var root = new WMORoot(filePath);

            if (!mpqManager.FileExists(filePath))
            {
                log.Error("WMO file does not exist: ", filePath);
            }

            using (var stream = mpqManager.OpenFile(filePath))
                using (var fileReader = new BinaryReader(stream))
                {
                    uint type   = 0;
                    uint size   = 0;
                    long curPos = AdvanceToNextChunk(fileReader, 0, ref type, ref size);

                    if (type == Signatures.MVER)
                    {
                        // Version
                        ReadMVER(fileReader, root);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MVER");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    if (type == Signatures.MOHD)
                    {
                        // Root Header
                        ReadMOHD(fileReader, root);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MOHD");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    if (type == Signatures.MOTX)
                    {
                        // Texture Names
                        ReadMOTX(fileReader, root, size);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MOTX");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    if (type == Signatures.MOMT)
                    {
                        // Materials
                        ReadMOMT(fileReader, root);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MOMT");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    if (type == Signatures.MOGN)
                    {
                        ReadMOGN(fileReader, root, size);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MOGN");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    if (type == Signatures.MOGI)
                    {
                        // Group Information
                        ReadMOGI(fileReader, root);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MOGI");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    if (type == Signatures.MOSB)
                    {
                        // Skybox (always 0 now, its no longer handled in WMO)
                        ReadMOSB(fileReader, root);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MOSB");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    if (type == Signatures.MOPV)
                    {
                        // Portal Vertices
                        ReadMOPV(fileReader, root);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MOPV");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    if (type == Signatures.MOPT)
                    {
                        // Portal Information
                        ReadMOPT(fileReader, root);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MOPT");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    if (type == Signatures.MOPR)
                    {
                        // Portal Relations
                        ReadMOPR(fileReader, root);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MOPR");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    if (type == Signatures.MOVV)
                    {
                        // Visible Vertices
                        ReadMOVV(fileReader, root, size);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MOVV");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    if (type == Signatures.MOVB)
                    {
                        // Visible Blocks
                        ReadMOVB(fileReader, root, size);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MOVB");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    if (type == Signatures.MOLT)
                    {
                        // Lights
                        ReadMOLT(fileReader, root);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MOLT");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    if (type == Signatures.MODS)
                    {
                        // Doodad Set
                        ReadMODS(fileReader, root);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MODS");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    if (type == Signatures.MODN)
                    {
                        // Doodad Names
                        ReadMODN(fileReader, root, size);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MODN");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    if (type == Signatures.MODD)
                    {
                        // Doodad Definitions
                        ReadMODD(fileReader, root, size);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MODD");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    if (type == Signatures.MFOG)
                    {
                        // Fog info
                        ReadMFOG(fileReader, root, size);
                    }
                    else
                    {
                        Console.WriteLine("WMO Root missing required chunk MFOG");
                    }
                    curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                    // Theres only 1 optional chunk in a WMO root
                    if (fileReader.BaseStream.Position < fileReader.BaseStream.Length)
                    {
                        if (type == Signatures.MCVP)
                        {
                            ReadMCVP(fileReader, root, size);
                        }

                        //curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);
                    }
                }


            return(root);
        }
Exemple #25
0
 static void ReadMVER(BinaryReader br, WMORoot wmo)
 {
     wmo.Version = br.ReadInt32();
 }
Exemple #26
0
        static void ReadMOVV(BinaryReader br, WMORoot wmo, uint size)
        {
            wmo.VisibleVertices = new Vector3[size/12]; // 12 = sizeof(Vector3), but we can't use sizeof with Vector3

            for (int i = 0; i < wmo.VisibleVertices.Length; i++)
            {
                wmo.VisibleVertices[i] = br.ReadVector3();
            }
        }
Exemple #27
0
        static void ReadMOVB(BinaryReader br, WMORoot wmo, uint size)
        {
            uint blockCount = size/4;
            wmo.VisibleBlocks = new VertexSpan[blockCount];

            for (int i = 0; i < blockCount; i++)
            {
                wmo.VisibleBlocks[i] = new VertexSpan
                                           {
                                               StartVertex = br.ReadInt16(),
                                               VertexCount = br.ReadInt16()
                                           };
            }
        }
Exemple #28
0
        static void ReadMOTX(BinaryReader br, WMORoot wmo, uint size)
        {
            wmo.Textures = new Dictionary<int, string>();

            long endPos = br.BaseStream.Position + size;
            while (br.BaseStream.Position < endPos)
            {
                if (br.PeekByte() == 0)
                {
                    br.BaseStream.Position++;
                }
                else
                {
                    wmo.Textures.Add((int) (size - (endPos - br.BaseStream.Position)), br.ReadCString());
                }
            }
        }
Exemple #29
0
        static void ReadMOLT(BinaryReader br, WMORoot wmo)
        {
            wmo.LightInfo = new LightInformation[wmo.Header.LightCount];

            for (int i = 0; i < wmo.LightInfo.Length; i++)
            {
                var light = new LightInformation
                                {
                                    Byte_1 = br.ReadByte(),
                                    Byte_2 = br.ReadByte(),
                                    Byte_3 = br.ReadByte(),
                                    Byte_4 = br.ReadByte(),
                                    Color = br.ReadColor4(),
                                    Position = br.ReadVector3(),
                                    Intensity = br.ReadSingle(),
                                    AttenStart = br.ReadSingle(),
                                    AttenEnd = br.ReadSingle(),
                                    Float_4 = br.ReadSingle(),
                                    Float_5 = br.ReadSingle(),
                                    Float_6 = br.ReadSingle(),
                                    Float_7 = br.ReadSingle()
                                };

                //FixVector3(ref light.position);

                wmo.LightInfo[i] = light;
            }
        }
Exemple #30
0
        static void ReadMOPV(BinaryReader br, WMORoot wmo)
        {
            // PortalCount of 4 x Vector3 to form a rectangle for the doorway
            uint vertexCount = wmo.Header.PortalCount*4;
            wmo.PortalVertices = new Vector3[vertexCount];

            for (var i=0; i<vertexCount; i++)
            {
                wmo.PortalVertices[i] = br.ReadVector3();
            }
        }
Exemple #31
0
        static void ReadMOGI(BinaryReader br, WMORoot wmo)
        {
            wmo.GroupInformation = new GroupInformation[wmo.Header.GroupCount];

            for (int i = 0; i < wmo.GroupInformation.Length; i++)
            {
                var g = new GroupInformation {
                                                 Flags = (WMOGroupFlags) br.ReadUInt32(),
                                                 BoundingBox = new BoundingBox(br.ReadWMOVector3(), br.ReadWMOVector3()),
                                                 NameIndex = br.ReadInt32()
                                             };

                wmo.GroupInformation[i] = g;
            }
        }
        private static void WriteGroups(BinaryWriter writer, WMORoot root)
        {
            if (root.GroupInformation == null) return;
            if (root.Groups == null) return;

            writer.Write(root.GroupInformation.Length);
            for (var i = 0; i < root.GroupInformation.Length; i++)
            {
                var info = root.GroupInformation[i];
                var group = root.Groups[i];

                writer.Write((uint)info.Flags);
                writer.Write(info.BoundingBox);
                writer.Write(group.Header.WMOGroupId);

                WriteGroupDoodadRefs(writer, root, group);

                writer.Write(group.Header.HasMLIQ);
                if (group.Header.HasMLIQ)
                {
                    WriteGroupLiquidInfo(writer, group);
                }

                writer.Write(group.Vertices);
                WriteBSPTree(writer, group);
            }
        }
Exemple #33
0
        static void ReadMODD(BinaryReader br, WMORoot wmo, uint size)
        {
            // Why oh why is wmo.Header.DoodadCount wrong sometimes
            // 40 is the size of DoodadDefinition
            wmo.DoodadDefinitions = new DoodadDefinition[size / 40];

            for (var i = 0; i < wmo.DoodadDefinitions.Length; i++)
            {
                var dd = new DoodadDefinition
                             {
                                 NameIndex = br.ReadInt32(),
                                 Position = br.ReadVector3(),
                                 Rotation = br.ReadQuaternion(),
                                 Scale = br.ReadSingle(),
                                 Color = br.ReadColor4()
                             };

                if (dd.NameIndex != -1)
                {
                    if(!wmo.DoodadFiles.TryGetValue(dd.NameIndex, out dd.FilePath))
                    {
                        dd.FilePath = "";
                        log.Error(String.Format("Doodad File Path for index: {0} missing from the Dictionary!", dd.NameIndex));
                    }
                }

                wmo.DoodadDefinitions[i] = dd;
            }
        }
Exemple #34
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="root"></param>
 /// <param name="index">The index into the WMOs GroupList that refers to this WMOGroup.</param>
 public WMOGroup(WMORoot root, int index)
 {
     Root = root;
     Index = index;
 }
Exemple #35
0
        static void ReadMCVP(BinaryReader br, WMORoot wmo, uint size)
        {
            wmo.ComplexVolumePlanes = new Plane[size/(4*sizeof (float))];

            for (int i = 0; i < wmo.ComplexVolumePlanes.Length; i++)
            {
                wmo.ComplexVolumePlanes[i] = br.ReadPlane();
            }
        }
Exemple #36
0
        public static WMORoot Process(MpqManager mpqManager, string filePath)
        {
            var root = new WMORoot(filePath);

            if (!mpqManager.FileExists(filePath))
            {
                log.Error("WMO file does not exist: ", filePath);
            }

            using (var stream = mpqManager.OpenFile(filePath))
            using (var fileReader = new BinaryReader(stream))
            {
                uint type = 0;
                uint size = 0;
                long curPos = AdvanceToNextChunk(fileReader, 0, ref type, ref size);

                if (type == Signatures.MVER)
                {
                    // Version
                    ReadMVER(fileReader, root);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MVER");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                if (type == Signatures.MOHD)
                {
                    // Root Header
                    ReadMOHD(fileReader, root);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MOHD");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                if (type == Signatures.MOTX)
                {
                    // Texture Names
                    ReadMOTX(fileReader, root, size);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MOTX");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                if (type == Signatures.MOMT)
                {
                    // Materials
                    ReadMOMT(fileReader, root);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MOMT");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                if (type == Signatures.MOGN)
                {
                    ReadMOGN(fileReader, root, size);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MOGN");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                if (type == Signatures.MOGI)
                {
                    // Group Information
                    ReadMOGI(fileReader, root);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MOGI");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                if (type == Signatures.MOSB)
                {
                    // Skybox (always 0 now, its no longer handled in WMO)
                    ReadMOSB(fileReader, root);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MOSB");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                if (type == Signatures.MOPV)
                {
                    // Portal Vertices
                    ReadMOPV(fileReader, root);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MOPV");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                if (type == Signatures.MOPT)
                {
                    // Portal Information
                    ReadMOPT(fileReader, root);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MOPT");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                if (type == Signatures.MOPR)
                {
                    // Portal Relations
                    ReadMOPR(fileReader, root);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MOPR");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                if (type == Signatures.MOVV)
                {
                    // Visible Vertices
                    ReadMOVV(fileReader, root, size);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MOVV");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                if (type == Signatures.MOVB)
                {
                    // Visible Blocks
                    ReadMOVB(fileReader, root, size);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MOVB");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                if (type == Signatures.MOLT)
                {
                    // Lights
                    ReadMOLT(fileReader, root);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MOLT");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                if (type == Signatures.MODS)
                {
                    // Doodad Set
                    ReadMODS(fileReader, root);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MODS");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                if (type == Signatures.MODN)
                {
                    // Doodad Names
                    ReadMODN(fileReader, root, size);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MODN");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                if (type == Signatures.MODD)
                {
                    // Doodad Definitions
                    ReadMODD(fileReader, root, size);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MODD");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                if (type == Signatures.MFOG)
                {
                    // Fog info
                    ReadMFOG(fileReader, root, size);
                }
                else
                {
                    Console.WriteLine("WMO Root missing required chunk MFOG");
                }
                curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);

                // Theres only 1 optional chunk in a WMO root
                if (fileReader.BaseStream.Position < fileReader.BaseStream.Length)
                {
                    if (type == Signatures.MCVP)
                    {
                        ReadMCVP(fileReader, root, size);
                    }

                    //curPos = AdvanceToNextChunk(fileReader, curPos, ref type, ref size);
                }

            }

            return root;
        }
Exemple #37
0
        private static void TransformWMO(MapObjectDefinition currentMODF, WMORoot currentWMO)
        {
            currentWMO.ClearCollisionData();
            var position = currentMODF.Position;
            var posX     = (position.X - TerrainConstants.CenterPoint) * -1;
            var posY     = (position.Y - TerrainConstants.CenterPoint) * -1;
            var origin   = new Vector3(posX, posY, position.Z);
            //origin = new Vector3(0.0f);

            //DrawWMOPositionPoint(origin, currentWMO);
            //DrawBoundingBox(currentMODF.Extents, Color.Purple, currentWMO);

            //var rotateZ = Matrix.CreateRotationZ(0*RadiansPerDegree);
            var rotateZ = Matrix.CreateRotationZ((currentMODF.OrientationB + 180) * RadiansPerDegree);
            //var rotateX = Matrix.CreateRotationX(currentMODF.OrientationC * RadiansPerDegree);
            //var rotateY = Matrix.CreateRotationY(currentMODF.OrientationA * RadiansPerDegree);

            int offset;


            foreach (var currentGroup in currentWMO.Groups)
            {
                if (currentGroup == null)
                {
                    continue;
                }
                //if (!currentGroup.Header.HasMLIQ) continue;

                var usedTris      = new Dictionary <Index3, int>();
                var wmoTrisUnique = new List <Index3>();

                foreach (var node in currentGroup.BSPNodes)
                {
                    if (node.TriIndices == null)
                    {
                        continue;
                    }
                    foreach (var index3 in node.TriIndices)
                    {
                        if (usedTris.ContainsKey(index3))
                        {
                            continue;
                        }

                        usedTris.Add(index3, 0);
                        wmoTrisUnique.Add(index3);
                    }
                }

                var newIndices = new Dictionary <int, int>();
                foreach (var tri in wmoTrisUnique)
                {
                    int newIndex;
                    if (!newIndices.TryGetValue(tri.Index0, out newIndex))
                    {
                        newIndex = currentWMO.WmoVertices.Count;
                        newIndices.Add(tri.Index0, newIndex);

                        var basePosVec     = currentGroup.Vertices[tri.Index0];
                        var rotatedPosVec  = Vector3.Transform(basePosVec, rotateZ);
                        var finalPosVector = rotatedPosVec + origin;
                        currentWMO.WmoVertices.Add(finalPosVector);
                    }
                    currentWMO.WmoIndices.Add(newIndex);

                    if (!newIndices.TryGetValue(tri.Index1, out newIndex))
                    {
                        newIndex = currentWMO.WmoVertices.Count;
                        newIndices.Add(tri.Index1, newIndex);

                        var basePosVec     = currentGroup.Vertices[tri.Index1];
                        var rotatedPosVec  = Vector3.Transform(basePosVec, rotateZ);
                        var finalPosVector = rotatedPosVec + origin;
                        currentWMO.WmoVertices.Add(finalPosVector);
                    }
                    currentWMO.WmoIndices.Add(newIndex);

                    if (!newIndices.TryGetValue(tri.Index2, out newIndex))
                    {
                        newIndex = currentWMO.WmoVertices.Count;
                        newIndices.Add(tri.Index2, newIndex);

                        var basePosVec     = currentGroup.Vertices[tri.Index2];
                        var rotatedPosVec  = Vector3.Transform(basePosVec, rotateZ);
                        var finalPosVector = rotatedPosVec + origin;
                        currentWMO.WmoVertices.Add(finalPosVector);
                    }
                    currentWMO.WmoIndices.Add(newIndex);
                }

                //for (var i = 0; i < currentGroup.Vertices.Count; i++)
                //{
                //    var basePosVector = currentGroup.Vertices[i];
                //    var rotatedPosVector = Vector3.Transform(basePosVector, rotateZ);
                //    var finalPosVector = rotatedPosVector + origin;

                //    //var baseNormVector = currentGroup.Normals[i];
                //    //var rotatedNormVector = Vector3.Transform(baseNormVector, rotateZ);

                //    currentWMO.WmoVertices.Add(finalPosVector);
                //}

                //for (var index = 0; index < currentGroup.Indices.Count; index++)
                //{
                //    currentWMO.WmoIndices.Add(currentGroup.Indices[index].Index0 + offset);
                //    currentWMO.WmoIndices.Add(currentGroup.Indices[index].Index1 + offset);
                //    currentWMO.WmoIndices.Add(currentGroup.Indices[index].Index2 + offset);
                //}

                // WMO Liquids
                if (!currentGroup.Header.HasMLIQ)
                {
                    continue;
                }

                var liqInfo   = currentGroup.LiquidInfo;
                var liqOrigin = liqInfo.BaseCoordinates;

                offset = currentWMO.WmoVertices.Count;
                for (var xStep = 0; xStep < liqInfo.XVertexCount; xStep++)
                {
                    for (var yStep = 0; yStep < liqInfo.YVertexCount; yStep++)
                    {
                        var xPos    = liqOrigin.X + xStep * TerrainConstants.UnitSize;
                        var yPos    = liqOrigin.Y + yStep * TerrainConstants.UnitSize;
                        var zPosTop = liqInfo.HeightMapMax[xStep, yStep];

                        var liqVecTop = new Vector3(xPos, yPos, zPosTop);

                        var rotatedTop = Vector3.Transform(liqVecTop, rotateZ);
                        var vecTop     = rotatedTop + origin;

                        currentWMO.WmoLiquidVertices.Add(vecTop);
                    }
                }

                for (var row = 0; row < liqInfo.XTileCount; row++)
                {
                    for (var col = 0; col < liqInfo.YTileCount; col++)
                    {
                        if ((liqInfo.LiquidTileFlags[row, col] & 0x0F) == 0x0F)
                        {
                            continue;
                        }

                        var index = ((row + 1) * (liqInfo.YVertexCount) + col);
                        currentWMO.WmoLiquidIndices.Add(offset + index);

                        index = (row * (liqInfo.YVertexCount) + col);
                        currentWMO.WmoLiquidIndices.Add(offset + index);

                        index = (row * (liqInfo.YVertexCount) + col + 1);
                        currentWMO.WmoLiquidIndices.Add(offset + index);

                        index = ((row + 1) * (liqInfo.YVertexCount) + col + 1);
                        currentWMO.WmoLiquidIndices.Add(offset + index);

                        index = ((row + 1) * (liqInfo.YVertexCount) + col);
                        currentWMO.WmoLiquidIndices.Add(offset + index);

                        index = (row * (liqInfo.YVertexCount) + col + 1);
                        currentWMO.WmoLiquidIndices.Add(offset + index);
                    }
                }
            }

            //Rotate the M2s to the new orientation
            if (currentWMO.WMOM2s != null)
            {
                foreach (var currentM2 in currentWMO.WMOM2s)
                {
                    offset = currentWMO.WmoVertices.Count;
                    for (var i = 0; i < currentM2.Vertices.Count; i++)
                    {
                        var basePosition    = currentM2.Vertices[i];
                        var rotatedPosition = Vector3.Transform(basePosition, rotateZ);
                        var finalPosition   = rotatedPosition + origin;

                        //var rotatedNormal = Vector3.Transform(basePosition, rotateZ);

                        currentWMO.WmoM2Vertices.Add(finalPosition);
                    }

                    foreach (var index in currentM2.Indices)
                    {
                        currentWMO.WmoM2Indices.Add(index + offset);
                    }
                }
            }
        }
Exemple #38
0
        static void ReadMOPT(BinaryReader br, WMORoot wmo)
        {
            wmo.PortalInformation = new PortalInformation[wmo.Header.PortalCount];

            for (var i = 0; i < wmo.Header.PortalCount; i++)
            {
                var p = new PortalInformation
                            {
                                Vertices = new VertexSpan
                                               {
                                                   StartVertex = br.ReadInt16(),
                                                   VertexCount = br.ReadInt16(),
                                               },
                                Plane = br.ReadPlane()
                            };
                wmo.PortalInformation[i] = p;
            }
        }
        private static void ExtractWMOGroups(string filePath, WMORoot root)
        {
            for (var grpIndex = 0; grpIndex < root.Header.GroupCount; grpIndex++)
            {
                var newFile = filePath.Substring(0, filePath.LastIndexOf('.'));
                var newFilePath = String.Format("{0}_{1:000}.wmo", newFile, grpIndex);

                var group = WMOGroupParser.Process(WDTExtractor.MpqManager, newFilePath, root, grpIndex);
                if (group == null) continue;

                root.Groups[grpIndex] = group;
            }
        }
Exemple #40
0
        static void ReadMOPR(BinaryReader br, WMORoot wmo)
        {
            wmo.PortalRelations = new PortalRelation[wmo.Header.PortalCount];

            for (int i = 0; i < wmo.PortalRelations.Length; i++)
            {
                var r = new PortalRelation
                {
                    PortalIndex = br.ReadUInt16(),
                    GroupIndex = br.ReadUInt16(),
                    Side = br.ReadInt16()
                };
                br.ReadInt16(); // filler

                wmo.PortalRelations[i] = r;
            }
        }
        private static void PrepareWMOGroupDoodadReferences(WMORoot root, WMOGroup wmoGroup)
        {
            foreach (var dRefId in wmoGroup.DoodadReferences)
            {
                var def = root.DoodadDefinitions[dRefId];
                if (def == null) continue;
                if (string.IsNullOrEmpty(def.FilePath)) continue;
                if (TileExtractor.ModelsToIgnore.Contains(def.FilePath)) continue;

                // Calculate and store the models' transform matrices
                Matrix scaleMatrix;
                Matrix.CreateScale(def.Scale, out scaleMatrix);

                Matrix rotMatrix;
                Matrix.CreateFromQuaternion(ref def.Rotation, out rotMatrix);

                Matrix modelToWMO;
                Matrix.Multiply(ref scaleMatrix, ref rotMatrix, out modelToWMO);

                Matrix wmoToModel;
                Matrix.Invert(ref modelToWMO, out wmoToModel);
                def.ModelToWMO = modelToWMO;
                def.WMOToModel = wmoToModel;

                M2Model model;
                if (!LoadedM2Models.TryGetValue(def.FilePath, out model))
                {
                    log.Error(String.Format("M2Model file: {0} missing from the Dictionary!", def.FilePath));
                    continue;
                }

                // Calculate the wmoSpace bounding box for this model
                CalculateModelsWMOSpaceBounds(def, model);
            }
        }
Exemple #42
0
        static void ReadMOMT(BinaryReader br, WMORoot wmo)
        {
            wmo.Materials = new Material[wmo.Header.TextureCount];

            for (int i = 0; i < wmo.Materials.Length; i++)
            {
                var mt = new Material
                             {
                                 Flags = (MaterialFlags)br.ReadUInt32(),
                                 Int_1 = br.ReadUInt32(),
                                 BlendMode = br.ReadInt32(),
                                 TextureNameStart = br.ReadInt32(),
                                 SidnColor = br.ReadColor4(),
                                 FrameSidnColor = br.ReadColor4(),
                                 TextureNameEnd = br.ReadInt32(),
                                 DiffColor = br.ReadColor4(),
                                 GroundType = br.ReadInt32(),
                                 Float_1 = br.ReadSingle(),
                                 Float_2 = br.ReadSingle(),
                                 Int_2 = br.ReadInt32(),
                                 Int_3 = br.ReadInt32(),
                                 Int_4 = br.ReadInt32()
                             };

                // these 2 are set in RAM in the client to the associated HTEXTUREs
                br.ReadUInt32();// 0x38
                br.ReadUInt32();// 0x3C

                wmo.Materials[i] = mt;

                //if (mt.Flags != 0)
                    //Console.WriteLine();
            }
        }
        private static void WriteGroupDoodadRefs(BinaryWriter writer, WMORoot root, WMOGroup group)
        {
            if (group.DoodadReferences.IsNullOrEmpty())
            {
                writer.Write(0);
                return;
            }

            var list = new List<int>();
            foreach (var defId in group.DoodadReferences)
            {
                var def = root.DoodadDefinitions[defId];
                if (def == null) continue;
                if (TileExtractor.ModelsToIgnore.Contains(def.FilePath)) continue;

                list.Add(defId);
            }

            writer.Write(list);
        }
Exemple #44
0
 static void ReadMOSB(BinaryReader br, WMORoot wmo)
 {
     // skyboxes moved to light.dbc
 }
        private static void WriteWMO(BinaryWriter writer, WMORoot root)
        {
            if (root == null)
            {
                Console.WriteLine("Cannot write null WMORoot to file.");
                return;
            }

            // Magic fileType
            writer.Write(wmoFileType);

            writer.Write(root.Header.BoundingBox);
            writer.Write(root.Header.WMOId);

            WriteDoodadDefinitions(writer, root);

            WriteGroups(writer, root);
        }
Exemple #46
0
 static void ReadMOSB(BinaryReader br, WMORoot wmo)
 {
     // skyboxes moved to light.dbc
 }
Exemple #47
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="root"></param>
 /// <param name="index">The index into the WMOs GroupList that refers to this WMOGroup.</param>
 public WMOGroup(WMORoot root, int index)
 {
     Root  = root;
     Index = index;
 }
Exemple #48
0
        private static void TransformWMO(MapObjectDefinition currentMODF, WMORoot currentWMO)
        {
            currentWMO.ClearCollisionData();
            var position = currentMODF.Position;
            var posX = (position.X - TerrainConstants.CenterPoint)*-1;
            var posY = (position.Y - TerrainConstants.CenterPoint)*-1;
            var origin = new Vector3(posX, posY, position.Z);
            //origin = new Vector3(0.0f);

            //DrawWMOPositionPoint(origin, currentWMO);
            //DrawBoundingBox(currentMODF.Extents, Color.Purple, currentWMO);

            //var rotateZ = Matrix.CreateRotationZ(0*RadiansPerDegree);
            var rotateZ = Matrix.CreateRotationZ((currentMODF.OrientationB + 180)*RadiansPerDegree);
            //var rotateX = Matrix.CreateRotationX(currentMODF.OrientationC * RadiansPerDegree);
            //var rotateY = Matrix.CreateRotationY(currentMODF.OrientationA * RadiansPerDegree);

            int offset;

            foreach (var currentGroup in currentWMO.Groups)
            {
                if (currentGroup == null) continue;
                //if (!currentGroup.Header.HasMLIQ) continue;

                var usedTris = new Dictionary<Index3, int>();
                var wmoTrisUnique = new List<Index3>();

                foreach (var node in currentGroup.BSPNodes)
                {
                    if (node.TriIndices == null) continue;
                    foreach (var index3 in node.TriIndices)
                    {
                        if (usedTris.ContainsKey(index3)) continue;

                        usedTris.Add(index3, 0);
                        wmoTrisUnique.Add(index3);
                    }
                }

                var newIndices = new Dictionary<int, int>();
                foreach (var tri in wmoTrisUnique)
                {
                    int newIndex;
                    if (!newIndices.TryGetValue(tri.Index0, out newIndex))
                    {
                        newIndex = currentWMO.WmoVertices.Count;
                        newIndices.Add(tri.Index0, newIndex);

                        var basePosVec = currentGroup.Vertices[tri.Index0];
                        var rotatedPosVec = Vector3.Transform(basePosVec, rotateZ);
                        var finalPosVector = rotatedPosVec + origin;
                        currentWMO.WmoVertices.Add(finalPosVector);
                    }
                    currentWMO.WmoIndices.Add(newIndex);

                    if (!newIndices.TryGetValue(tri.Index1, out newIndex))
                    {
                        newIndex = currentWMO.WmoVertices.Count;
                        newIndices.Add(tri.Index1, newIndex);

                        var basePosVec = currentGroup.Vertices[tri.Index1];
                        var rotatedPosVec = Vector3.Transform(basePosVec, rotateZ);
                        var finalPosVector = rotatedPosVec + origin;
                        currentWMO.WmoVertices.Add(finalPosVector);
                    }
                    currentWMO.WmoIndices.Add(newIndex);

                    if (!newIndices.TryGetValue(tri.Index2, out newIndex))
                    {
                        newIndex = currentWMO.WmoVertices.Count;
                        newIndices.Add(tri.Index2, newIndex);

                        var basePosVec = currentGroup.Vertices[tri.Index2];
                        var rotatedPosVec = Vector3.Transform(basePosVec, rotateZ);
                        var finalPosVector = rotatedPosVec + origin;
                        currentWMO.WmoVertices.Add(finalPosVector);
                    }
                    currentWMO.WmoIndices.Add(newIndex);
                }

                //for (var i = 0; i < currentGroup.Vertices.Count; i++)
                //{
                //    var basePosVector = currentGroup.Vertices[i];
                //    var rotatedPosVector = Vector3.Transform(basePosVector, rotateZ);
                //    var finalPosVector = rotatedPosVector + origin;

                //    //var baseNormVector = currentGroup.Normals[i];
                //    //var rotatedNormVector = Vector3.Transform(baseNormVector, rotateZ);

                //    currentWMO.WmoVertices.Add(finalPosVector);
                //}

                //for (var index = 0; index < currentGroup.Indices.Count; index++)
                //{
                //    currentWMO.WmoIndices.Add(currentGroup.Indices[index].Index0 + offset);
                //    currentWMO.WmoIndices.Add(currentGroup.Indices[index].Index1 + offset);
                //    currentWMO.WmoIndices.Add(currentGroup.Indices[index].Index2 + offset);
                //}

                // WMO Liquids
                if (!currentGroup.Header.HasMLIQ) continue;

                var liqInfo = currentGroup.LiquidInfo;
                var liqOrigin = liqInfo.BaseCoordinates;

                offset = currentWMO.WmoVertices.Count;
                for (var xStep = 0; xStep < liqInfo.XVertexCount; xStep++)
                {
                    for (var yStep = 0; yStep < liqInfo.YVertexCount; yStep++)
                    {
                        var xPos = liqOrigin.X + xStep * TerrainConstants.UnitSize;
                        var yPos = liqOrigin.Y + yStep * TerrainConstants.UnitSize;
                        var zPosTop = liqInfo.HeightMapMax[xStep, yStep];

                        var liqVecTop = new Vector3(xPos, yPos, zPosTop);

                        var rotatedTop = Vector3.Transform(liqVecTop, rotateZ);
                        var vecTop = rotatedTop + origin;

                        currentWMO.WmoLiquidVertices.Add(vecTop);
                    }
                }

                for (var row = 0; row < liqInfo.XTileCount; row++)
                {
                    for (var col = 0; col < liqInfo.YTileCount; col++)
                    {
                        if ((liqInfo.LiquidTileFlags[row, col] & 0x0F) == 0x0F) continue;

                        var index = ((row + 1)*(liqInfo.YVertexCount) + col);
                        currentWMO.WmoLiquidIndices.Add(offset + index);

                        index = (row*(liqInfo.YVertexCount) + col);
                        currentWMO.WmoLiquidIndices.Add(offset + index);

                        index = (row*(liqInfo.YVertexCount) + col + 1);
                        currentWMO.WmoLiquidIndices.Add(offset + index);

                        index = ((row + 1)*(liqInfo.YVertexCount) + col + 1);
                        currentWMO.WmoLiquidIndices.Add(offset + index);

                        index = ((row + 1)*(liqInfo.YVertexCount) + col);
                        currentWMO.WmoLiquidIndices.Add(offset + index);

                        index = (row*(liqInfo.YVertexCount) + col + 1);
                        currentWMO.WmoLiquidIndices.Add(offset + index);
                    }
                }
            }

            //Rotate the M2s to the new orientation
            if (currentWMO.WMOM2s != null)
            {
                foreach (var currentM2 in currentWMO.WMOM2s)
                {
                    offset = currentWMO.WmoVertices.Count;
                    for (var i = 0; i < currentM2.Vertices.Count; i++)
                    {
                        var basePosition = currentM2.Vertices[i];
                        var rotatedPosition = Vector3.Transform(basePosition, rotateZ);
                        var finalPosition = rotatedPosition + origin;

                        //var rotatedNormal = Vector3.Transform(basePosition, rotateZ);

                        currentWMO.WmoM2Vertices.Add(finalPosition);
                    }

                    foreach (var index in currentM2.Indices)
                    {
                        currentWMO.WmoM2Indices.Add(index + offset);
                    }
                }
            }
        }