private static void ReadWMOGroups(BinaryReader br, ExtractedWMO wmo)
        {
            var groupCount = br.ReadInt32();
            var groupList  = new List <ExtractedWMOGroup>(groupCount);

            for (int i = 0; i < groupCount; i++)
            {
                var group = new ExtractedWMOGroup();
                group.Flags     = (WMOGroupFlags)br.ReadUInt32();
                group.Bounds    = br.ReadBoundingBox();
                group.GroupId   = br.ReadUInt32();
                group.ModelRefs = br.ReadInt32List();

                group.HasLiquid = br.ReadBoolean();
                if (group.HasLiquid)
                {
                    ReadWMOGroupLiquidInfo(br, group);
                }
                group.WmoVertices = br.ReadVector3List();

                ReadBSPTree(br, group);

                groupList.Add(group);
            }
            wmo.Groups = groupList;
        }
        private static void ReadBSPTree(BinaryReader br, ExtractedWMOGroup group)
        {
            var rootId = br.ReadInt16();
            var nodeCount = br.ReadInt32();
            var nodeList = new List<BSPNode>(nodeCount);
            for (var i = 0; i < nodeCount; i++)
            {
                var node = new BSPNode {
                                           flags = (BSPNodeFlags) br.ReadByte(),
                                           negChild = br.ReadInt16(),
                                           posChild = br.ReadInt16(),
                                           planeDist = br.ReadSingle(),
                                           TriIndices = br.ReadIndex3List()
                                       };

                nodeList.Add(node);
            }

            group.Tree = new BSPTree(nodeList, rootId);
        }
        private static void ReadBSPTree(BinaryReader br, ExtractedWMOGroup group)
        {
            var rootId    = br.ReadInt16();
            var nodeCount = br.ReadInt32();
            var nodeList  = new List <BSPNode>(nodeCount);

            for (var i = 0; i < nodeCount; i++)
            {
                var node = new BSPNode {
                    flags      = (BSPNodeFlags)br.ReadByte(),
                    negChild   = br.ReadInt16(),
                    posChild   = br.ReadInt16(),
                    planeDist  = br.ReadSingle(),
                    TriIndices = br.ReadIndex3List()
                };

                nodeList.Add(node);
            }

            group.Tree = new BSPTree(nodeList, rootId);
        }
        private static void ReadWMOGroupLiquidInfo(BinaryReader br, ExtractedWMOGroup group)
        {
            group.LiquidBaseCoords = br.ReadVector3();
            group.LiqTileCountX    = br.ReadInt32();
            group.LiqTileCountY    = br.ReadInt32();

            group.LiquidTileMap = new bool[group.LiqTileCountX, group.LiqTileCountY];
            for (var y = 0; y < group.LiqTileCountY; y++)
            {
                for (var x = 0; x < group.LiqTileCountX; x++)
                {
                    group.LiquidTileMap[x, y] = br.ReadBoolean();
                }
            }

            group.LiquidHeights = new float[group.LiqTileCountX + 1, group.LiqTileCountY + 1];
            for (var y = 0; y < group.LiqTileCountY + 1; y++)
            {
                for (var x = 0; x < group.LiqTileCountX + 1; x++)
                {
                    group.LiquidHeights[x, y] = br.ReadSingle();
                }
            }
        }
        private static void ReadWMOGroups(BinaryReader br, ExtractedWMO wmo)
        {
            var groupCount = br.ReadInt32();
            var groupList = new List<ExtractedWMOGroup>(groupCount);
            for (int i = 0; i < groupCount; i++)
            {
                var group = new ExtractedWMOGroup();
                group.Flags = (WMOGroupFlags) br.ReadUInt32();
                group.Bounds = br.ReadBoundingBox();
                group.GroupId = br.ReadUInt32();
                group.ModelRefs = br.ReadInt32List();

                group.HasLiquid = br.ReadBoolean();
                if (group.HasLiquid)
                {
                    ReadWMOGroupLiquidInfo(br, group);
                }
                group.WmoVertices = br.ReadVector3List();

                ReadBSPTree(br, group);

                groupList.Add(group);
            }
            wmo.Groups = groupList;
        }
        private static void ReadWMOGroupLiquidInfo(BinaryReader br, ExtractedWMOGroup group)
        {
            group.LiquidBaseCoords = br.ReadVector3();
            group.LiqTileCountX = br.ReadInt32();
            group.LiqTileCountY = br.ReadInt32();

            group.LiquidTileMap = new bool[group.LiqTileCountX, group.LiqTileCountY];
            for (var y = 0; y < group.LiqTileCountY; y++)
            {
                for (var x = 0; x < group.LiqTileCountX; x++)
                {
                    group.LiquidTileMap[x, y] = br.ReadBoolean();
                }
            }

            group.LiquidHeights = new float[group.LiqTileCountX + 1, group.LiqTileCountY + 1];
            for (var y = 0; y < group.LiqTileCountY + 1; y++)
            {
                for (var x = 0; x < group.LiqTileCountX + 1; x++)
                {
                    group.LiquidHeights[x, y] = br.ReadSingle();
                }
            }
        }