예제 #1
0
파일: WDT.cs 프로젝트: primax/WCell
		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;
		}
예제 #2
0
        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);
            }
        }
예제 #3
0
        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);
            }
        }
예제 #4
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) * 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);
					}
				}
			}
		}
예제 #5
0
		/// <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;
		}
예제 #6
0
        /// <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;
        }