MODF Class - WMO Placement Information
Exemplo n.º 1
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)*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 Dictionary<Index3, int>();
                var wmoTrisUnique = new List<Index3>();

                foreach (var node in currentGroup.BSPNodes)
                {
                    if (node.TriIndices == null) continue;
                    foreach (var index3 in node.TriIndices)
                    {
                        if (usedTris.ContainsKey(index3)) continue;

                        usedTris.Add(index3, 0);
                        wmoTrisUnique.Add(index3);
                    }
                }

                var newIndices = new Dictionary<int, int>();
                foreach (var tri in wmoTrisUnique)
                {
                    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);
                    }
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Adds a WMO to the manager
        /// </summary>
        /// <param name="currentMODF">MODF (placement information for this WMO)</param>
        public void AddWMO(MapObjectDefinition currentMODF)
        {
            _fileNames.Add(currentMODF.FilePath);

            // Parse the WMORoot
            var wmoRoot = WMORootParser.Process(MpqTerrainManager.MpqManager, 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 = WMOGroupParser.Process(MpqTerrainManager.MpqManager, 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 List<M2.M2>((int) doodadSetCount);
                for (var i = doodadSetOffset; i < (doodadSetOffset + doodadSetCount); i++)
                {
                    var curDoodadDef = wmoRoot.DoodadDefinitions[i];
                    var curM2 = M2ModelParser.Process(MpqTerrainManager.MpqManager, 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.Add(rotatedM2);
                }
            }

            TransformWMO(currentMODF, wmoRoot);

            var bounds = new BoundingBox(wmoRoot.WmoVertices);
            wmoRoot.Bounds = bounds;

            WMOs.Add(wmoRoot);
        }
Exemplo n.º 3
0
        private static void PrepareWMOInfo(MapObjectDefinition def)
        {
            TerrainConstants.TilePositionToWorldPosition(ref def.Position);
            TerrainConstants.TileExtentsToWorldExtents(ref def.Extents);

            Matrix modelToWorld;
            Matrix.CreateRotationZ(MathHelper.ToRadians(def.OrientationB + 180), out modelToWorld);
            Matrix worldToModel;
            Matrix.Invert(ref modelToWorld, out worldToModel);
            def.WMOToWorld = modelToWorld;
            def.WorldToWMO = worldToModel;

            // Reposition the m2s contained within the wmos
            //WMORoot root;
            //if (!LoadedWmoRoots.TryGetValue(def.FilePath, out root))
            //{
            //    log.Error(String.Format("WMORoot file: {0} missing from the Dictionary!", def.FilePath));
            //    continue;
            //}

            //var setIndices = new List<int> { 0 };
            //if (def.DoodadSet > 0) setIndices.Add(def.DoodadSet);

            //foreach (var index in setIndices)
            //{
            //    var doodadSet = root.DoodadSets[index];
            //    for (var i = 0; i < doodadSet.InstanceCount; i++)
            //    {
            //        var dDef = root.DoodadDefinitions[doodadSet.FirstInstanceIndex + i];
            //        if (string.IsNullOrEmpty(dDef.FilePath)) continue;

            //        M2Model model;
            //        if (!LoadedM2Models.TryGetValue(dDef.FilePath, out model))
            //        {
            //            log.Error(String.Format("M2Model file: {0} missing from the Dictionary!", dDef.FilePath));
            //            continue;
            //        }

            //        // Calculate and store the models' transform matrices
            //        Matrix scaleMatrix;
            //        Matrix.CreateScale(dDef.Scale, out scaleMatrix);

            //        Matrix rotMatrix;
            //        Matrix.CreateFromQuaternion(ref dDef.Rotation, out rotMatrix);

            //        Matrix modelToWMO;
            //        Matrix.Multiply(ref scaleMatrix, ref rotMatrix, out modelToWMO);

            //        Matrix wmoToModel;
            //        Matrix.Invert(ref modelToWMO, out wmoToModel);
            //        dDef.ModelToWMO = modelToWMO;
            //        dDef.WMOToModel = wmoToModel;

            //        // Calculate the wmoSpace bounding box for this model
            //        var wmoSpaceVecs = new List<Vector3>(model.BoundingVertices.Length);
            //        for (var j = 0; j < model.BoundingVertices.Length; j++)
            //        {
            //            Vector3 rotated;
            //            Vector3.Transform(ref model.BoundingVertices[i], ref modelToWMO, out rotated);

            //            Vector3 final;
            //            Vector3.Add(ref rotated, ref dDef.Position, out final);
            //            wmoSpaceVecs.Add(final);
            //        }

            //        dDef.Extents = new BoundingBox(wmoSpaceVecs.ToArray());
            //        def.M2Refs.Add(dDef);
            //    }
            //}
        }
Exemplo n.º 4
0
        private static void LoadWMO(MpqManager manager, MapObjectDefinition def)
        {
            if (LoadedWmoIds.Contains(def.UniqueId)) return;
            LoadedWmoIds.Add(def.UniqueId);

            if (!WorldObjectExtractor.LoadedWMORoots.ContainsKey(def.FilePath))
            {
                var root = WMORootParser.Process(manager, def.FilePath);
                WorldObjectExtractor.LoadedWMORoots.Add(def.FilePath, root);
            }

            PrepareWMOInfo(def);
        }
Exemplo n.º 5
0
 public void AddWMO(MapObjectDefinition currentMODF)
 {
     if (currentMODF is ExtractedWMODefinition)
     {
         Add((ExtractedWMODefinition)currentMODF);
     }
 }
Exemplo n.º 6
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);
            }
        }