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 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; } }
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); }
private static void ExtractWMOM2s(WMORoot root) { foreach (var def in root.DoodadDefinitions) { ExtractM2Model(def.FilePath); } }
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; } }
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); } }
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; } }
private static void ExtractWMOM2s(MapObjectDefinition wmo, WMORoot root, TileModels tileModels) { var setIndices = new List <int> { 0 }; if (wmo.DoodadSet != 0) { setIndices.Add(wmo.DoodadSet); } foreach (var index in setIndices) { var set = root.DoodadSets[index]; for (var k = 0; k < set.InstanceCount; k++) { var dd = root.DoodadDefinitions[(int)set.FirstInstanceIndex + k]; if (string.IsNullOrEmpty(dd.FilePath)) { continue; } var model = ExtractModel(wmo, dd); if (model.Vertices.Length < 1) { continue; } tileModels.Models.Add(model); } } }
public void AddDungeon(WMORoot model, MODF.MODFEntry def) { var verts = new List <Vector3>(); var inds = new List <Triangle <uint> >(); MapChunk.InsertWMOGeometry(def, model, verts, inds); AddGeometry(verts, inds); }
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(); } }
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() }; } }
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 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; } }
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; } }
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; } }
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); } }
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()); } } }
/// <summary> /// Gets a WMOGroup from the WMO Group file /// </summary> /// <param name="librarian"></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(MpqLibrarian librarian, string filePath, WMORoot root, int groupIndex) { if (!librarian.FileExists(filePath)) { log.Error("WMOGroup file does not exist: ", filePath); } var currentWMOGroup = new WMOGroup(root, groupIndex); using (var stream = librarian.OpenFile(filePath)) using (var br = new BinaryReader(stream)) { ReadRequiredChunks(br, currentWMOGroup); ReadOptionalChunks(br, currentWMOGroup); } return(currentWMOGroup); }
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); }
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 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); } } }
/// <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]; }
static void ReadWMO() { const string path = @"World\wmo\Northrend\HowlingFjord\DaggercapCave.wmo"; var wmo = new WMORoot(path); using (var sw = new StreamWriter(Path.GetFileNameWithoutExtension(path) + ".obj", false)) { //sw.WriteLine("o " + filename); var nf = System.Globalization.CultureInfo.InvariantCulture.NumberFormat; int vo = 0; foreach (var g in wmo.Groups) { foreach (var v in g.MOVT.Vertices) { sw.WriteLine("v " + v.X.ToString(nf) + " " + v.Z.ToString(nf) + " " + v.Y.ToString(nf)); } foreach (var t in g.MOVI.Indices) { sw.WriteLine("f " + (t.V0 + vo + 1) + " " + (t.V1 + vo + 1) + " " + (t.V2 + vo + 1)); } vo += g.MOVT.Vertices.Count(); if (g.LiquidVertices == null || g.LiquidIndices == null) { continue; } foreach (var v in g.LiquidVertices) { sw.WriteLine("v " + v.X.ToString(nf) + " " + v.Z.ToString(nf) + " " + v.Y.ToString(nf)); } foreach (var t in g.LiquidIndices) { sw.WriteLine("f " + (t.V0 + vo + 1) + " " + (t.V1 + vo + 1) + " " + (t.V2 + vo + 1)); } vo += g.LiquidVertices.Count; } } }
public bool Open(uint fileId, WMORoot rootWmo) { Stream stream = Program.CascHandler.OpenFile((int)fileId); if (stream == null) { Console.WriteLine("No such file."); return(false); } using (BinaryReader reader = new(stream)) { long fileLength = reader.BaseStream.Length; while (reader.BaseStream.Position < fileLength) { string fourcc = reader.ReadStringFromChars(4, true); uint size = reader.ReadUInt32(); if (fourcc == "MOGP")//Fix sizeoff = Data size. { size = 68; } long nextpos = reader.BaseStream.Position + size; if (fourcc == "MOGP")//header { groupName = reader.ReadInt32(); descGroupName = reader.ReadInt32(); mogpFlags = reader.ReadInt32(); for (var i = 0; i < 3; ++i) { bbcorn1[i] = reader.ReadSingle(); } for (var i = 0; i < 3; ++i) { bbcorn2[i] = reader.ReadSingle(); } moprIdx = reader.ReadUInt16(); moprNItems = reader.ReadUInt16(); nBatchA = reader.ReadUInt16(); nBatchB = reader.ReadUInt16(); nBatchC = reader.ReadUInt32(); fogIdx = reader.ReadUInt32(); groupLiquid = reader.ReadUInt32(); groupWMOID = reader.ReadUInt32(); // according to WoW.Dev Wiki: if (Convert.ToBoolean(rootWmo.flags & 4)) { groupLiquid = GetLiquidTypeId(groupLiquid); } else if (groupLiquid == 15) { groupLiquid = 0; } else { groupLiquid = GetLiquidTypeId(groupLiquid + 1); } if (groupLiquid != 0) { liquflags |= 2; } } else if (fourcc == "MOPY") { mopy_size = (int)size; nTriangles = (int)size / 2; MOPY = reader.ReadString((int)size); } else if (fourcc == "MOVI") { MOVI = new ushort[size / 2]; for (var i = 0; i < size / 2; ++i) { MOVI[i] = reader.ReadUInt16(); } } else if (fourcc == "MOVT") { MOVT = new float[size / 4]; for (var i = 0; i < size / 4; ++i) { MOVT[i] = reader.ReadSingle(); } nVertices = size / 12; } else if (fourcc == "MONR") { } else if (fourcc == "MOTV") { } else if (fourcc == "MOBA") { MOBA = new ushort[size / 2]; moba_size = (int)(size / 2); for (var i = 0; i < size / 2; ++i) { MOBA[i] = reader.ReadUInt16(); } } else if (fourcc == "MODR") { for (var i = 0; i < size / 2; ++i) { DoodadReferences.Add(reader.Read <ushort>()); } } else if (fourcc == "MLIQ") { liquflags |= 1; hlq = reader.Read <WMOLiquidHeader>(); LiquEx_size = 8 * hlq.xverts * hlq.yverts; LiquEx = new WMOLiquidVert[hlq.xverts * hlq.yverts]; for (var i = 0; i < hlq.xverts * hlq.yverts; ++i) { LiquEx[i] = reader.Read <WMOLiquidVert>(); } int nLiquBytes = hlq.xtiles * hlq.ytiles; LiquBytes = reader.ReadBytes(nLiquBytes); // Determine legacy liquid type if (groupLiquid == 0) { for (int i = 0; i < hlq.xtiles * hlq.ytiles; ++i) { if ((LiquBytes[i] & 0xF) != 15) { groupLiquid = GetLiquidTypeId((uint)(LiquBytes[i] & 0xF) + 1); break; } } } /* std::ofstream llog("Buildings/liquid.log", ios_base::out | ios_base::app); * llog << filename; * llog << "\nbbox: " << bbcorn1[0] << ", " << bbcorn1[1] << ", " << bbcorn1[2] << " | " << bbcorn2[0] << ", " << bbcorn2[1] << ", " << bbcorn2[2]; * llog << "\nlpos: " << hlq->pos_x << ", " << hlq->pos_y << ", " << hlq->pos_z; * llog << "\nx-/yvert: " << hlq->xverts << "/" << hlq->yverts << " size: " << size << " expected size: " << 30 + hlq->xverts*hlq->yverts*8 + hlq->xtiles*hlq->ytiles << std::endl; * llog.close(); */ } reader.BaseStream.Seek((int)nextpos, SeekOrigin.Begin); } } return(true); }
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) * MathUtil.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 HashSet <Index3>(); var wmoTrisUnique = new List <Index3>(); foreach (var node in currentGroup.BSPNodes) { if (node.TriIndices == null) { continue; } foreach (var triangle in node.TriIndices) { if (usedTris.Contains(triangle)) { continue; } usedTris.Add(triangle); wmoTrisUnique.Add(triangle); } } var newIndices = new Dictionary <int, int>(); foreach (var tri in wmoTrisUnique) { // add all vertices, uniquely 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.WmoLiquidVertices.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.WmoM2Vertices.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); } } } }
static void ReadMOSB(BinaryReader br, WMORoot wmo) { // skyboxes moved to light.dbc }
static void ReadMVER(BinaryReader br, WMORoot wmo) { wmo.Version = br.ReadInt32(); }