public static ExtractedWMO Process(string basePath, MapId mapId, string path) { basePath = Path.Combine(basePath, mapId.ToString()); var filePath = Path.Combine(basePath, path); filePath = Path.ChangeExtension(filePath, ".wmo"); if (!File.Exists(filePath)) { throw new FileNotFoundException("Extracted M2 file not found: {0}", filePath); } var wmo = new ExtractedWMO(); using (var file = File.OpenRead(filePath)) using (var br = new BinaryReader(file)) { var type = br.ReadString(); if (type != fileType) { br.Close(); throw new InvalidDataException(string.Format("WMO file in invalid format: {0}", filePath)); } wmo.Extents = br.ReadBoundingBox(); wmo.WMOId = br.ReadUInt32(); ReadWMODoodadDefs(br, wmo); ReadWMOGroups(br, wmo); } return wmo; }
private static void ReadWMODoodadDefs(BinaryReader br, ExtractedWMO wmo) { var numSets = br.ReadInt32(); var setList = new List<Dictionary<int, ExtractedWMOM2Definition>>(numSets); for (var i = 0; i < numSets; i++) { var numDefs = br.ReadInt32(); var defDict = new Dictionary<int, ExtractedWMOM2Definition>(numDefs); for (var j = 0; j < numDefs; j++) { var key = br.ReadInt32(); var def = new ExtractedWMOM2Definition { FilePath = br.ReadString(), Position = br.ReadVector3(), Extents = br.ReadBoundingBox(), WMOToModel = br.ReadMatrix(), ModeltoWMO = br.ReadMatrix() }; defDict.Add(key, def); } setList.Add(defDict); } wmo.WMOM2Defs = setList; }
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 Transform(ExtractedWMO wmo, List<ExtractedM2> m2s, ExtractedWMODefinition def) { foreach (var group in wmo.Groups) { for (var j = 0; j < group.WmoVertices.Count; j++) { var vec = group.WmoVertices[j]; Vector3 rotatedVector; Vector3.Transform(ref vec, ref def.WMOToWorld, out rotatedVector); // Translate Vector3 finalVector; Vector3.Add(ref rotatedVector, ref def.Position, out finalVector); group.WmoVertices[j] = finalVector; if (!group.HasLiquid) continue; var liqOrigin = group.LiquidBaseCoords; for (var xStep = 0; xStep <= group.LiqTileCountX; xStep++) { for (var yStep = 0; yStep <= group.LiqTileCountY; yStep++) { var xPos = liqOrigin.X + xStep * TerrainConstants.UnitSize; var yPos = liqOrigin.Y + yStep * TerrainConstants.UnitSize; var zPosTop = group.LiquidHeights[xStep, yStep]; var liqVecTop = new Vector3(xPos, yPos, zPosTop); Vector3 rotatedTop; Vector3.Transform(ref liqVecTop, ref def.WMOToWorld, out rotatedTop); Vector3 vecTop; Vector3.Add(ref rotatedTop, ref def.Position, out vecTop); group.LiquidVertices.Add(vecTop); } } } } foreach (var m2 in m2s) { for (var j = 0; j < m2.BoundingVertices.Count; j++) { var vec = m2.BoundingVertices[j]; Vector3 rotatedVector; Vector3.Transform(ref vec, ref def.WMOToWorld, out rotatedVector); // Translate Vector3 finalVector; Vector3.Add(ref rotatedVector, ref def.Position, out finalVector); m2.BoundingVertices[j] = finalVector; } } }