public WMORoot GetOrReadWMO(MapObjectDefinition definition) { WMORoot wmo; if (!WMOs.TryGetValue(definition.FilePath, out wmo)) { WMOs.Add(definition.FilePath, wmo = WMOReader.ReadWMO(WCellTerrainSettings.GetDefaultMPQFinder(), definition)); } return wmo; }
static void ReadMODF(BinaryReader fileReader, ADT adt) { var type = fileReader.ReadUInt32(); var size = fileReader.ReadUInt32(); long endPos = fileReader.BaseStream.Position + size; while (fileReader.BaseStream.Position < endPos) { var objectDef = new MapObjectDefinition(); int nameIndex = fileReader.ReadInt32(); // 4 bytes objectDef.FilePath = adt.ObjectFiles[nameIndex]; objectDef.UniqueId = fileReader.ReadUInt32(); // 4 bytes // This Position appears to be in the wrong order. // To get WoW coords, read it as: {Y, Z, X} var Y = fileReader.ReadSingle(); var Z = fileReader.ReadSingle(); var X = fileReader.ReadSingle(); objectDef.Position = new Vector3(X, Y, Z); // 12 bytes objectDef.OrientationA = fileReader.ReadSingle(); // 4 Bytes objectDef.OrientationB = fileReader.ReadSingle(); // 4 Bytes objectDef.OrientationC = fileReader.ReadSingle(); // 4 Bytes var min = new Vector3(); min.Y = fileReader.ReadSingle(); min.Z = fileReader.ReadSingle(); min.X = fileReader.ReadSingle(); var max = new Vector3(); max.Y = fileReader.ReadSingle(); max.Z = fileReader.ReadSingle(); max.X = fileReader.ReadSingle(); objectDef.Extents = new BoundingBox(min, max); // 12*2 bytes objectDef.Flags = fileReader.ReadUInt16(); // 2 bytes objectDef.DoodadSetId = fileReader.ReadUInt16(); // 2 bytes objectDef.NameSet = fileReader.ReadUInt16(); // 2 bytes fileReader.ReadUInt16(); // padding adt.ObjectDefinitions.Add(objectDef); } }
static void ReadMODF(BinaryReader fileReader, WDT wdt) { var type = fileReader.ReadUInt32(); var size = fileReader.ReadUInt32(); var endPos = fileReader.BaseStream.Position + size; while (fileReader.BaseStream.Position < endPos) { var objectDef = new MapObjectDefinition(); var nameIndex = fileReader.ReadInt32(); // 4 bytes objectDef.FilePath = wdt.WmoFiles[nameIndex]; objectDef.UniqueId = fileReader.ReadUInt32(); // 4 bytes objectDef.Position = fileReader.ReadVector3(); // 12 bytes objectDef.OrientationA = fileReader.ReadSingle(); // 4 Bytes objectDef.OrientationB = fileReader.ReadSingle(); // 4 Bytes objectDef.OrientationC = fileReader.ReadSingle(); // 4 Bytes objectDef.Extents = fileReader.ReadBoundingBox(); // 12*2 bytes objectDef.Flags = fileReader.ReadUInt16(); // 2 bytes objectDef.DoodadSetId = fileReader.ReadUInt16(); // 2 bytes objectDef.NameSet = fileReader.ReadUInt16(); // 2 bytes fileReader.ReadUInt16(); // padding wdt.WmoDefinitions.Add(objectDef); } }
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.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); } } } }
/// <summary> /// Adds a WMO to the manager /// </summary> public static WMORoot ReadWMO(MpqLibrarian librarian, MapObjectDefinition currentMODF) { // Parse the WMORoot var wmoRoot = WMOReader.ReadWMO(librarian, currentMODF.FilePath); // Parse the WMOGroups for (var wmoGroup = 0; wmoGroup < wmoRoot.Header.GroupCount; wmoGroup++) { var newFile = wmoRoot.FilePath.Substring(0, wmoRoot.FilePath.LastIndexOf('.')); var currentFilePath = String.Format("{0}_{1:000}.wmo", newFile, wmoGroup); var group = WMOGroupReader.Process(librarian, currentFilePath, wmoRoot, wmoGroup); wmoRoot.Groups[wmoGroup] = group; } //wmoRoot.DumpLiqChunks(); // Parse in the WMO's M2s var curDoodadSet = currentMODF.DoodadSetId; var setIndices = new List<int> { 0 }; if (curDoodadSet > 0) setIndices.Add(curDoodadSet); foreach (var index in setIndices) { var doodadSetOffset = wmoRoot.DoodadSets[index].FirstInstanceIndex; var doodadSetCount = wmoRoot.DoodadSets[index].InstanceCount; wmoRoot.WMOM2s = new M2[(int)doodadSetCount]; for (var i = doodadSetOffset; i < (doodadSetOffset + doodadSetCount); i++) { var curDoodadDef = wmoRoot.DoodadDefinitions[i]; var curM2 = M2Reader.ReadM2(librarian, curDoodadDef.FilePath); var tempIndices = new List<int>(); for (var j = 0; j < curM2.BoundingTriangles.Length; j++) { var tri = curM2.BoundingTriangles[j]; tempIndices.Add(tri.Index2); tempIndices.Add(tri.Index1); tempIndices.Add(tri.Index0); } var rotatedM2 = TransformWMOM2(curM2, tempIndices, curDoodadDef); wmoRoot.WMOM2s[i - doodadSetOffset] = rotatedM2; } } TransformWMO(currentMODF, wmoRoot); var bounds = new BoundingBox(wmoRoot.WmoVertices); wmoRoot.Bounds = bounds; return wmoRoot; }
/// <summary> /// Adds a WMO to the manager /// </summary> public static WMORoot ReadWMO(MpqLibrarian librarian, MapObjectDefinition currentMODF) { // Parse the WMORoot var wmoRoot = WMOReader.ReadWMO(librarian, currentMODF.FilePath); if (wmoRoot == null) return null; // Parse the WMOGroups for (var wmoGroup = 0; wmoGroup < wmoRoot.Header.GroupCount; wmoGroup++) { var newFile = wmoRoot.FilePath.Substring(0, wmoRoot.FilePath.LastIndexOf('.')); var currentFilePath = String.Format("{0}_{1:000}.wmo", newFile, wmoGroup); var group = WMOGroupReader.Process(librarian, currentFilePath, wmoRoot, wmoGroup); wmoRoot.Groups[wmoGroup] = group; } //wmoRoot.DumpLiqChunks(); // Parse in the WMO's M2s var curDoodadSet = currentMODF.DoodadSetId; var setIndices = new List<int> { 0 }; if (curDoodadSet > 0) setIndices.Add(curDoodadSet); var setDefs = new List<DoodadSet>(setIndices.Count); foreach (var index in setIndices) { if (index >= wmoRoot.DoodadSets.Length) { log.Error("Invalid index {0} into wmoRoot.DoodadSet array with id", index, curDoodadSet); continue; } setDefs.Add(wmoRoot.DoodadSets[index]); } var m2List = new List<M2>(); foreach (var def in setDefs) { var doodadSetOffset = def.FirstInstanceIndex; var doodadSetCount = def.InstanceCount; for (var i = doodadSetOffset; i < (doodadSetOffset + doodadSetCount); i++) { var curDoodadDef = wmoRoot.DoodadDefinitions[i]; if (string.IsNullOrEmpty(curDoodadDef.FilePath)) { log.Error("Encountered Doodad with empty file path"); continue; } var curM2 = M2Reader.ReadM2(librarian, curDoodadDef.FilePath, true); var tempIndices = new List<int>(); for (var j = 0; j < curM2.BoundingTriangles.Length; j++) { var tri = curM2.BoundingTriangles[j]; tempIndices.Add(tri.Index2); tempIndices.Add(tri.Index1); tempIndices.Add(tri.Index0); } var rotatedM2 = TransformWMOM2(curM2, tempIndices, curDoodadDef); m2List.Add(rotatedM2); } } wmoRoot.WMOM2s = m2List.ToArray(); TransformWMO(currentMODF, wmoRoot); var bounds = new BoundingBox(wmoRoot.WmoVertices); wmoRoot.Bounds = bounds; return wmoRoot; }