Beispiel #1
0
        private static void PrepareM2Info(MapDoodadDefinition def, M2Model model)
        {
            TerrainConstants.TilePositionToWorldPosition(ref def.Position);

            Matrix scaleMatrix;

            Matrix.CreateScale(def.Scale, out scaleMatrix);

            var rotateZ = Matrix.CreateRotationZ(MathHelper.ToRadians(def.OrientationB + 180));
            var rotateY = Matrix.CreateRotationY(MathHelper.ToRadians(def.OrientationA));
            var rotateX = Matrix.CreateRotationX(MathHelper.ToRadians(def.OrientationC));

            var modelToWorld = Matrix.Multiply(scaleMatrix, rotateZ);

            modelToWorld     = Matrix.Multiply(modelToWorld, rotateX);
            modelToWorld     = Matrix.Multiply(modelToWorld, rotateY);
            def.ModelToWorld = modelToWorld;

            Matrix worldToModel;

            Matrix.Invert(ref modelToWorld, out worldToModel);
            def.WorldToModel = worldToModel;

            CalculateModelBounds(def, model);
        }
Beispiel #2
0
        /// <summary>
        /// Writes all height maps to the default MapDir
        /// </summary>
        public static void ExportMapTiles(WDT wdt)
        {
            // Map data should only be stored per map
            ClearObjectData();
            var path = Path.Combine(TerrainDisplayConfig.MapDir, wdt.Entry.Id.ToString());

            if (wdt.IsWMOOnly)
            {
                // This Map has no Tiles, but the MODF still needs to be written
                // These maps will be considered to have one tile at {0, 0} with only one MODF written therein
                var adt = ExtractWMOOnly(wdt);
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                using (var file = File.Create(Path.Combine(path, TerrainConstants.GetMapFilename(0, 0))))
                {
                    WriteTileInfo(file, adt);
                }
                return;
            }

            // Read in the ADT data - this includes height and liquid maps, WMO information and M2 information
            TerrainInfo = ExtractMapTiles(wdt);

            // Write the processed data to files
            var count = 0;

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            for (var tileX = 0; tileX < TerrainConstants.TilesPerMapSide; tileX++)
            {
                for (var tileY = 0; tileY < TerrainConstants.TilesPerMapSide; tileY++)
                {
                    var adt = TerrainInfo[tileY, tileX];
                    if (adt == null)
                    {
                        continue;
                    }

                    var filePath = Path.Combine(path, TerrainConstants.GetMapFilename(tileX, tileY));
                    using (var file = File.Create(filePath))
                    {
                        WriteTileInfo(file, adt);
                        file.Close();
                    }
                    count++;
                }
            }

            log.Info("Extracted {0} tiles for {1}.", count, wdt.Entry.Id);
        }
Beispiel #3
0
        public static void WriteM2Files()
        {
            log.Info("Extracting partial M2 world objects - This might take a few minutes.....");
            var startTime  = DateTime.Now;
            var wowRootDir = ToolConfig.Instance.GetWoWDir();
            var outputDir  = ToolConfig.M2Dir;

            manager = new MpqManager(wowRootDir);

            var entryList = DBCMapReader.GetMapEntries();

            if (entryList == null)
            {
                log.Error("Could not retrieve MapEntries.");
                return;
            }

            foreach (var mapEntry in entryList)
            {
                //if (mapEntry.Id != (int)MapId.EasternKingdoms) continue;

                var dir     = mapEntry.MapDirName;
                var wdtDir  = Path.Combine(baseDir, dir);
                var wdtName = dir;

                var wdt = WDTParser.Process(manager, wdtDir, wdtName);
                if (wdt == null)
                {
                    continue;
                }

                var regionM2s = ExtractRegionM2s(wdt);

                var count = 0;
                var max   = regionM2s.HasTiles ? TerrainConstants.TilesPerMapSide : 1;
                for (var tileY = 0; tileY < max; tileY++)
                {
                    for (var tileX = 0; tileX < max; tileX++)
                    {
                        //if (tileX != 36) continue;
                        //if (tileY != 49) continue;

                        if (regionM2s.ObjectsByTile[tileX, tileY] == null)
                        {
                            continue;
                        }

                        // Don't bother writing tiles with no models.
                        var tileModels = regionM2s.ObjectsByTile[tileX, tileY];
                        if (tileModels.Models.Count == 0)
                        {
                            continue;
                        }

                        var path = Path.Combine(outputDir, mapEntry.Id.ToString());
                        if (!Directory.Exists(path))
                        {
                            Directory.CreateDirectory(path);
                        }
                        var file = File.Create(Path.Combine(path, TerrainConstants.GetM2File(tileX, tileY)));

                        WriteTileM2s(file, tileModels);
                        count++;
                        file.Close();
                    }
                }
                log.Info(count);
            }

            log.Info("Done ({0})", DateTime.Now - startTime);
        }
Beispiel #4
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);
            //    }
            //}
        }
Beispiel #5
0
        public static string GetInputMeshFile(MapId map, int tileX, int tileY)
        {
            var tileName = TerrainConstants.GetTileName(tileX, tileY);

            return(WCellTerrainSettings.RecastInputMeshFolder + (int)map + "/" + tileName + RecastAPI.InputMeshExtension);
        }
Beispiel #6
0
        /// <summary>
        /// Builds the mesh for a single tile.
        /// NOTE: This sets the Terrain's NavMesh property.
        /// In order to move between tiles, we need to generate one mesh for the entire map
        /// </summary>
        public void BuildMesh(TerrainTile tile)
        {
            // let recast build the navmesh and then call our callback
            var inputFile   = GetInputMeshFile(tile.Terrain.MapId, tile.TileX, tile.TileY);
            var navMeshFile = GetNavMeshFile(tile.Terrain.MapId, tile.TileX, tile.TileY);
            var exists      = DoesNavMeshExist(tile.Terrain.MapId, tile.TileX, tile.TileY);

            if (!exists)
            {
                var directory = new FileInfo(inputFile).Directory;
                if (directory != null)
                {
                    Directory.CreateDirectory(directory.FullName);
                }

                directory = new FileInfo(navMeshFile).Directory;
                if (directory != null)
                {
                    Directory.CreateDirectory(directory.FullName);
                }

                // export input mesh to file
                ExportRecastInputMesh(tile, inputFile);

                Console.WriteLine("Building new NavMesh...");
            }

            var start  = DateTime.Now;
            var result = RecastAPI.BuildMesh(
                GenerateTileId(tile),
                inputFile,
                navMeshFile,
                SmashMeshDlgt);

            if (result == 0)
            {
                throw new Exception("Could not build mesh for tile " + TerrainConstants.GetTileName(tile.TileX, tile.TileY) + " in map " + Terrain.MapId);
            }

            if (!exists)
            {
                Console.WriteLine("Done in {0:0.000}s", (DateTime.Now - start).TotalSeconds);
            }

            //// move all vertices above the surface
            //var mesh = tile.Terrain.NavMesh;
            //for (var i = 0; i < mesh.Vertices.Length; i++)
            //{
            //    var vert = mesh.Vertices[i];
            //    vert.Z += 0.001f;
            //    var ray = new Ray(vert, Vector3.Down);	// see if vertex is above surface
            //    var hit = tile.FindFirstHitTriangle(ray);
            //    if (hit == -1)
            //    {
            //        vert.Z -= 0.001f;

            //        // vertex is below surface
            //        ray = new Ray(vert, Vector3.Up);	// find surface right above mesh
            //        hit = tile.FindFirstHitTriangle(ray);
            //        if (hit != -1)
            //        {
            //            // set vertex height equal to terrain
            //            var tri = tile.GetTriangle(hit);
            //            var plane = new Plane(tri.Point1, tri.Point2, tri.Point3);
            //            Intersection.LineSegmentIntersectsPlane(ray.Position, ray.Direction, plane, out mesh.Vertices[i]);
            //        }
            //    }
            //}
        }
Beispiel #7
0
        /// <summary>
        ///  The filename of extracted heightfields
        /// </summary>
        public static string GetFileName(MapId map, int tileX, int tileY)
        {
            var path = GetMapDirectory(map);

            return(Path.Combine(path, TerrainConstants.GetTileName(tileX, tileY) + FileExtension));
        }