Ejemplo n.º 1
0
        private bool LoadTile(int tileX, int tileY)
        {
            if (!WDT.HasTile(tileX, tileY))
            {
                return(false);
            }

            if (IsTileLoaded(tileX, tileY))
            {
                return(false);
            }

            // Generate tile
            var tile = new ADT(Continent, tileX, tileY, WDT);

            tile.Read();
            tile.Generate();

            // Generate renderer
            var renderer = new ADTRenderer(Controller, tile);

            renderer.Generate();
            renderer.Bind(Controller.Shader);
            ADTRenderer.Renderers.Add(renderer);

            return(true);
        }
Ejemplo n.º 2
0
        public void LoadTileData()
        {
            s_Geometry = new Geometry.Geometry();
            // First read target tile to verify we have geometry and get bounding box
            // Read tile
            s_Tile.Read();
            // Generate relevant geometry
            s_Tile.Generate();
            // Append to our geometry
            s_Geometry.AddADT(s_Tile, false);

            // Generate the bounding box for the tile
            // (Because we need to cut the surrounding tiles later)
            Bounds = Geometry.Geometry.GetBoundingBox(X, Y, s_Geometry.Vertices);

            // We need to load the surrounding tiles because there sometimes is overlap in geometry to and from different tiles
            for (var y = Y - 1; y <= Y + 1; y++)
            {
                for (var x = X - 1; y <= X + 1; y++)
                {
                    // Skip target tile as we already added it
                    if (X == x && Y == y)
                    {
                        continue;
                    }

                    // Add a surrounding tile
                    var tile = new ADT(World, x, y);
                    tile.Read();
                    tile.Generate();
                    s_Geometry.AddADT(tile, false);
                }
            }
        }
Ejemplo n.º 3
0
        public void Build()
        {
            var geo = new Geometry.Geometry();

            Source.Read();
            geo.AddADT(Source);
        }
Ejemplo n.º 4
0
        public void TestGameAdt()
        {
            MpqManager.Initialize("S:\\WoW");
            var test = new ADT("World\\maps\\Northrend\\Northrend_43_29.adt");

            test.Read();

            Assert.AreEqual(test.MapChunks.Length, 16 * 16);
            Assert.IsNotNull(test.DoodadHandler.Vertices);
            Assert.IsNotNull(test.DoodadHandler.Triangles);
        }
Ejemplo n.º 5
0
        public static ADT GetAdt(string world, int x, int y)
        {
            //if (Cache.Adt.TryGetValue(new Tuple<int, int>(x, y), out adt))
            //    return adt;
            ADT adt = new ADT(GetAdtPath(world, x, y));

            if (adt.HasObjectData)
            {
                adt.Read();
            }
            //Cache.Adt.Add(new Tuple<int, int>(x, y), adt);
            return(adt);
        }
Ejemplo n.º 6
0
        public static ADT GetAdt(string world, int x, int y)
        {
            ADT adt = null;

            if (Cache.Adt.TryGetValue(new Tuple <int, int>(x, y), out adt))
            {
                return(adt);
            }
            adt = new ADT(GetAdtPath(world, x, y));
            adt.Read();
            Cache.Adt.Add(new Tuple <int, int>(x, y), adt);
            return(adt);
        }
Ejemplo n.º 7
0
        static void ReadADT()
        {
            //var adt = new ADT("Azeroth", 28, 28);
            //var adt = new ADT("Kalimdor", 32, 36);
            var adt = new ADT("PvPZone01", 32, 30);

            adt.Read();

            var geom = new Geometry();

            geom.AddADT(adt);
            geom.SaveWavefrontObject(Path.GetFileNameWithoutExtension(adt.Filename) + ".obj");
        }
Ejemplo n.º 8
0
        static void CreateNavmesh()
        {
            var geom = new Geometry();
            var sw   = Stopwatch.StartNew();
            var adt  = new ADT("Azeroth", 28, 28);

            adt.Read();
            sw.Stop();
            Console.WriteLine("Read ADT in {0}", sw.Elapsed);
            geom.AddADT(adt);
            sw.Restart();
            var bbox  = Geometry.GetBoundingBox(28, 28, geom.Vertices);
            var build = geom.GenerateNavmesh(bbox);

            sw.Stop();
            Console.WriteLine("Generated navmesh in {0}", sw.Elapsed);

            TestNavmesh(new SharpNav.TiledNavMesh(build));
        }
Ejemplo n.º 9
0
        static void ReadADTs()
        {
            const string continent = "Azeroth";
            var          allGeom   = new Geometry();

            var sw = new Stopwatch();

            for (int y = 27; y < 29; y++)
            {
                for (int x = 28; x < 30; x++)
                {
                    Console.Write("Parsing {0} [{1}, {2}]", continent, x, y);
                    sw.Start();
                    var adt = new ADT(continent, x, y);
                    adt.Read();
                    sw.Reset();
                    Console.WriteLine(" (done! {0}ms)", sw.ElapsedMilliseconds);
                    allGeom.AddADT(adt);
                }
            }

            allGeom.SaveWavefrontObject(continent + ".obj");
        }
Ejemplo n.º 10
0
        protected override void LoadContent()
        {
            _adt = new ADT(_path);
            _adt.Read();

            _terrain = new GeometryDrawer();
            _terrain.Initialize(Game, Color.Green, _adt.MapChunks.Select(mc => mc.Vertices),
                                _adt.MapChunks.Select(mc => mc.Triangles));

            var firstVert = _adt.MapChunks[0].Vertices[0];

            meshDisplay.Game.Camera.Camera.Position = new Vector3(firstVert.Y, firstVert.Z, firstVert.X);

            if (_adt.DoodadHandler.Triangles != null)
            {
                _doodads = new GeometryDrawer();
                _doodads.Initialize(Game, Color.Yellow, _adt.DoodadHandler.Vertices, _adt.DoodadHandler.Triangles);
            }

            if (_adt.WorldModelHandler.Triangles != null)
            {
                _wmos = new GeometryDrawer();
                _wmos.Initialize(Game, Color.Red, _adt.WorldModelHandler.Vertices, _adt.WorldModelHandler.Triangles);
            }

            if (_adt.LiquidHandler.Triangles != null)
            {
                _liquid = new GeometryDrawer();
                _liquid.Initialize(Game, Color.Blue, _adt.LiquidHandler.Vertices, _adt.LiquidHandler.Triangles);
            }

            _effect     = new BasicEffect(GraphicsDevice);
            _depthState = new DepthStencilState {
                DepthBufferEnable = true
            };
        }
Ejemplo n.º 11
0
        public byte[] Build(BaseLog log)
        {
            Log      = log;
            Geometry = new Geometry {
                Transform = true
            };

            {
                var main = new ADT(GetAdtPath(World, X, Y));
                main.Read();
                Geometry.AddAdt(main);
            }

            if (Geometry.Vertices.Count == 0 && Geometry.Triangles.Count == 0)
            {
                throw new InvalidOperationException("Can't build tile with empty geometry");
            }

            float[] bbMin, bbMax;
            CalculateTileBounds(out bbMin, out bbMax);
            Geometry.CalculateMinMaxHeight(out bbMin[1], out bbMax[1]);

            // again, we load everything - wasteful but who cares
            for (int ty = Y - 1; ty <= Y + 1; ty++)
            {
                for (int tx = X - 1; tx <= X + 1; tx++)
                {
                    try
                    {
                        // don't load main tile again
                        if (tx == X && ty == Y)
                        {
                            continue;
                        }

                        var adt = new ADT(GetAdtPath(World, tx, ty));
                        adt.Read();
                        Geometry.AddAdt(adt);
                    }
                    catch (FileNotFoundException)
                    {
                        // don't care - no file means no geometry
                    }
                }
            }

            Context = new RecastContext();
            Context.SetContextHandler(Log);

            // get raw geometry - lots of slowness here
            float[] vertices;
            int[]   triangles;
            byte[]  areas;
            Geometry.GetRawData(out vertices, out triangles, out areas);
            Geometry.Triangles.Clear();
            Geometry.Vertices.Clear();

            // add border
            bbMin[0] -= Config.BorderSize * Config.CellSize;
            bbMin[2] -= Config.BorderSize * Config.CellSize;
            bbMax[0] += Config.BorderSize * Config.CellSize;
            bbMax[2] += Config.BorderSize * Config.CellSize;

            Heightfield hf;
            int         width = Config.TileWidth + (Config.BorderSize * 2);

            if (!Context.CreateHeightfield(out hf, width, width, bbMin, bbMax, Config.CellSize, Config.CellHeight))
            {
                throw new OutOfMemoryException("CreateHeightfield ran out of memory");
            }

            Context.ClearUnwalkableTriangles(Config.WalkableSlopeAngle, ref vertices, ref triangles, areas);
            Context.RasterizeTriangles(ref vertices, ref triangles, ref areas, hf, Config.WalkableClimb);

            // Once all geometry is rasterized, we do initial pass of filtering to
            // remove unwanted overhangs caused by the conservative rasterization
            // as well as filter spans where the character cannot possibly stand.
            Context.FilterLowHangingWalkableObstacles(Config.WalkableClimb, hf);
            Context.FilterLedgeSpans(Config.WalkableHeight, Config.WalkableClimb, hf);
            Context.FilterWalkableLowHeightSpans(Config.WalkableHeight, hf);

            // Compact the heightfield so that it is faster to handle from now on.
            // This will result in more cache coherent data as well as the neighbours
            // between walkable cells will be calculated.
            CompactHeightfield chf;

            if (!Context.BuildCompactHeightfield(Config.WalkableHeight, Config.WalkableClimb, hf, out chf))
            {
                throw new OutOfMemoryException("BuildCompactHeightfield ran out of memory");
            }

            hf.Delete();

            // Erode the walkable area by agent radius.
            if (!Context.ErodeWalkableArea(Config.WalkableRadius, chf))
            {
                throw new OutOfMemoryException("ErodeWalkableArea ran out of memory");
            }

            // Prepare for region partitioning, by calculating distance field along the walkable surface.
            if (!Context.BuildDistanceField(chf))
            {
                throw new OutOfMemoryException("BuildDistanceField ran out of memory");
            }

            // Partition the walkable surface into simple regions without holes.
            if (!Context.BuildRegions(chf, Config.BorderSize, Config.MinRegionArea, Config.MergeRegionArea))
            {
                throw new OutOfMemoryException("BuildRegionsMonotone ran out of memory");
            }

            // Create contours.
            ContourSet cset;

            if (!Context.BuildContours(chf, Config.MaxSimplificationError, Config.MaxEdgeLength, out cset))
            {
                throw new OutOfMemoryException("BuildContours ran out of memory");
            }

            // Build polygon navmesh from the contours.
            PolyMesh pmesh;

            if (!Context.BuildPolyMesh(cset, Config.MaxVertsPerPoly, out pmesh))
            {
                throw new OutOfMemoryException("BuildPolyMesh ran out of memory");
            }

            // Build detail mesh.
            PolyMeshDetail dmesh;

            if (
                !Context.BuildPolyMeshDetail(pmesh, chf, Config.DetailSampleDistance, Config.DetailSampleMaxError,
                                             out dmesh))
            {
                throw new OutOfMemoryException("BuildPolyMeshDetail ran out of memory");
            }

            chf.Delete();
            cset.Delete();

            // Remove padding from the polymesh data. (Remove this odditity)
            pmesh.RemovePadding(Config.BorderSize);

            // Set flags according to area types (e.g. Swim for Water)
            pmesh.MarkAll();

            // get original bounds
            float[] tilebMin, tilebMax;
            CalculateTileBounds(out tilebMin, out tilebMax);
            tilebMin[1] = bbMin[1];
            tilebMax[1] = bbMax[1];

            // build off mesh connections for flightmasters
            // bMax and bMin are switched here because of the coordinate system transformation
            var taxis       = TaxiHelper.GetNodesInBBox(MapId, tilebMax.ToWoW(), tilebMin.ToWoW());
            var connections = new List <OffMeshConnection>();

            foreach (var taxi in taxis)
            {
                Log.Log(LogCategory.Warning,
                        "Flightmaster \"" + taxi.Name + "\", Id: " + taxi.Id + " Horde: " + taxi.IsHorde + " Alliance: " +
                        taxi.IsAlliance);

                var data = TaxiHelper.GetTaxiData(taxi);
                var from = taxi.Location.ToRecast().ToFloatArray();
                connections.AddRange(data.To.Select(to => new OffMeshConnection
                {
                    AreaId = PolyArea.Road,
                    Flags  = PolyFlag.FlightMaster,
                    From   = from,
                    To     = to.Value.Location.ToRecast().ToFloatArray(),
                    Radius = Config.WorldWalkableRadius,
                    Type   = ConnectionType.OneWay,
                    UserID = (uint)to.Key
                }));

                foreach (var target in data.To)
                {
                    Log.Log(LogCategory.Warning,
                            "\tPath to: \"" + target.Value.Name + "\" Id: " + target.Value.Id + " Path Id: " +
                            target.Key);
                }
            }

            byte[] tileData;
            if (!Detour.CreateNavMeshData(out tileData, pmesh, dmesh,
                                          X, Y, tilebMin, tilebMax,
                                          Config.WorldWalkableHeight, Config.WorldWalkableRadius,
                                          Config.WorldWalkableClimb, Config.CellSize,
                                          Config.CellHeight, Config.TileWidth,
                                          connections.ToArray()))
            {
                pmesh.Delete();
                dmesh.Delete();
                return(null);
            }

            pmesh.Delete();
            dmesh.Delete();
            Cache.Clear();
            GC.Collect();
            return(tileData);
        }