예제 #1
0
        public LiquidChunk(ADT adt, Chunk chunk)
        {
            Chunk = chunk;
            ADT   = adt;

            Read();
        }
예제 #2
0
        public void Read(ADT combinedFile)
        {
            foreach (var subChunk in Data.Chunks)
            {
                switch (subChunk.Name)
                {
                case "MVER":
                    combinedFile.MVER = new MVER(subChunk);
                    break;

                case "MAMP":
                    combinedFile.MAMP = new MAMP(subChunk);
                    break;

                // case "MFBO":
                //     combinedFile.MFBO = new MFBO(subChunk);
                //     break;
                case "MHDR":
                    combinedFile.MHDR = new MHDR(subChunk);
                    break;

                case "MH2O":
                    combinedFile.Liquid = new LiquidChunk(combinedFile, subChunk);
                    break;

                case "MCNK":
                    combinedFile.AddMapChunk(subChunk);
                    break;

                default:
                    Console.WriteLine($"Unhandled {subChunk.Name} chunk in model ADT.");
                    break;
                }
            }
        }
예제 #3
0
파일: LiquidChunk.cs 프로젝트: aeo24/WoWMap
        public LiquidChunk(ADT adt, Chunk chunk)
        {
            ADT = adt;
            Chunk = chunk;

            Read();
        }
예제 #4
0
파일: ADT.cs 프로젝트: WowDevs/WoWMap
        public void Read()
        {
            if (Type == ADTType.Normal)
            {
                ADTObjects = new ADT(World, X, Y, ADTType.Objects);
                ADTObjects.Read();

                //ADTTextures = new ADT(World, X, Y, ADTType.Textures);
                //ADTTextures.Read();
            }

            MapChunks = new MapChunk[16 * 16];
            int mcIdx = 0;

            foreach (var subChunk in Data.Chunks)
            {
                switch (subChunk.Name)
                {
                case "MHDR":
                    MHDR = new MHDR(subChunk);
                    break;

                case "MMDX":
                    MMDX = new MMDX(subChunk);
                    break;

                case "MMID":
                    MMID = new MMID(subChunk);
                    ReadDoodads();
                    break;

                case "MWMO":
                    MWMO = new MWMO(subChunk);
                    break;

                case "MWID":
                    MWID = new MWID(subChunk);
                    ReadModels();
                    break;

                case "MDDF":
                    MDDF = new MDDF(subChunk);
                    break;

                case "MODF":
                    MODF = new MODF(subChunk);
                    break;

                case "MH2O":
                    Liquid = new LiquidChunk(this, subChunk);
                    break;

                case "MCNK":
                    MapChunks[mcIdx++] = new MapChunk(this, subChunk);
                    break;
                }
            }
        }
예제 #5
0
파일: WMORoot.cs 프로젝트: shmilyzxt/WoWMap
        public WMORoot(string filename, ADT adt = null)
        {
            Filename = filename;
            ADT      = adt;

            Data = new ChunkData(filename);

            Read();
        }
예제 #6
0
파일: Program.cs 프로젝트: aeo24/WoWMap
        static void ReadADT()
        {
            var adt = new ADT("Azeroth", 32, 48);
            //var adt = new ADT("Kalimdor", 32, 36);
            adt.Read();

            var geom = new Geometry();
            geom.Transform = true;
            geom.AddADT(adt);
            geom.SaveWavefrontObject(Path.GetFileNameWithoutExtension(adt.Filename) + ".obj");
            WoWMap.Builders.ContinentBuilder b = new WoWMap.Builders.ContinentBuilder("Azeroth", 32, 48,1,1);
            b.Build();
        }
예제 #7
0
파일: ADT.cs 프로젝트: aeo24/WoWMap
        public void Read()
        {
            if (Type == ADTType.Normal)
            {
                ADTObjects = new ADT(World, X, Y, ADTType.Objects);
                ADTObjects.Read();

                //ADTTextures = new ADT(World, X, Y, ADTType.Textures);
                //ADTTextures.Read();
            }

            MapChunks = new MapChunk[16 * 16];
            int mcIdx = 0;

            foreach (var subChunk in Data.Chunks)
            {
                switch (subChunk.Name)
                {
                    case "MHDR":
                        MHDR = new MHDR(subChunk);
                        break;
                    case "MMDX":
                        MMDX = new MMDX(subChunk);
                        break;
                    case "MMID":
                        MMID = new MMID(subChunk);
                        ReadDoodads();
                        break;
                    case "MWMO":
                        MWMO = new MWMO(subChunk);
                        break;
                    case "MWID":
                        MWID = new MWID(subChunk);
                        ReadModels();
                        break;
                    case "MDDF":
                        MDDF = new MDDF(subChunk);
                        break;
                    case "MODF":
                        MODF = new MODF(subChunk);
                        break;
                    case "MH2O":
                        Liquid = new LiquidChunk(this, subChunk);
                        break;
                    case "MCNK":
                        MapChunks[mcIdx++] = new MapChunk(this, subChunk);
                        break;
                }
            }
        }
예제 #8
0
        public MapChunk(ADT adt, Chunk chunk, bool isObj0 = false)
        {
            ADT   = adt;
            Chunk = chunk;

            MCNK  = new MCNK(chunk);
            Holes = MCNK.Flags.HasFlag(MCNK.MCNKFlags.HighResolutionHoles) ? HighResHoles : TransformToHighRes(MCNK.Holes);

            var stream = chunk.GetStream();

            stream.Seek(chunk.Offset + MCNK.ChunkHeaderSize, SeekOrigin.Begin);

            Read(new ChunkData(stream, chunk.Size - MCNK.ChunkHeaderSize));
        }
예제 #9
0
파일: Geometry.cs 프로젝트: aeo24/WoWMap
 public void AddADT(ADT source)
 {
     foreach (var s in new ADT[] { source, source.ADTObjects, /* source.ADTTextures */ })
     {
         foreach (var mc in s.MapChunks)
         {
             if (mc.Vertices != null && mc.Vertices.Count() > 0 && mc.Indices != null && mc.Indices.Count > 0)
                 AddGeometry(mc.Vertices, mc.Indices);
             if (mc.WMOVertices != null && mc.WMOVertices.Count > 0 && mc.WMOIndices != null && mc.WMOIndices.Count > 0)
                 AddGeometry(mc.WMOVertices, mc.WMOIndices);
             if (mc.DoodadVertices != null && mc.DoodadVertices.Count > 0 && mc.DoodadIndices != null && mc.DoodadIndices.Count > 0)
                 AddGeometry(mc.DoodadVertices, mc.DoodadIndices);
         }
         if (s.Liquid != null && s.Liquid.Vertices != null && s.Liquid.Indices != null)
             AddGeometry(source.Liquid.Vertices, source.Liquid.Indices);
     }
 }
예제 #10
0
파일: MapChunk.cs 프로젝트: aeo24/WoWMap
        public MapChunk(ADT adt, Chunk chunk, bool isObj0 = false)
        {
            ADT = adt;
            Chunk = chunk;

            var stream = chunk.GetStream();
            if (adt.Type == ADTType.Normal)
            {
                MCNK = new MCNK(chunk);
                Holes = MCNK.Flags.HasFlag(MCNK.MCNKFlags.HighResolutionHoles) ? HighResHoles : TransformToHighRes(MCNK.Holes);

                stream.Seek(chunk.Offset + MCNK.ChunkHeaderSize, SeekOrigin.Begin);
                SubData = new ChunkData(stream, chunk.Size - MCNK.ChunkHeaderSize);
            }
            else
                SubData = new ChunkData(stream, chunk.Size);

            Read();
        }
예제 #11
0
        public void Read(ADT combinedFile)
        {
            var mcnkIdx = 0;

            foreach (var subChunk in Data.Chunks)
            {
                switch (subChunk.Name)
                {
                case "MMDX":
                    combinedFile.MMDX = new MMDX(subChunk);
                    break;

                case "MMID":
                    combinedFile.MMID = new MMID(subChunk);
                    break;

                case "MWMO":
                    combinedFile.MWMO = new MWMO(subChunk);
                    break;

                case "MWID":
                    combinedFile.MWID = new MWID(subChunk);
                    break;

                case "MDDF":
                    combinedFile.MDDF = new MDDF(subChunk);
                    break;

                case "MODF":
                    combinedFile.MODF = new MODF(subChunk);
                    break;

                case "MCNK":
                    combinedFile.UpdateMapChunk(subChunk, mcnkIdx++);
                    break;

                default:
                    Console.WriteLine($"Unhandled {subChunk.Name} chunk in Objects ADT.");
                    break;
                }
            }
        }
예제 #12
0
        public void Read(ADT combinedFile)
        {
            var mcnkIdx = 0;

            foreach (var subChunk in Data.Chunks)
            {
                switch (subChunk.Name)
                {
                case "MTEX":
                    combinedFile.MTEX = new MTEX(subChunk);
                    break;

                case "MCNK":
                    combinedFile.UpdateMapChunk(subChunk, mcnkIdx++);
                    break;

                default:
                    Console.WriteLine($"Unhandled {subChunk.Name} chunk in Textures ADT.");
                    break;
                }
            }
        }
예제 #13
0
파일: Program.cs 프로젝트: aeo24/WoWMap
        static void ReadADTs()
        {
            const string continent = "Azeroth";
            var allGeom = new Geometry();

            var sw = new Stopwatch();
            for (int y = 49; y < 50; y++)
            {
                for (int x = 31; x < 33; 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");
        }
예제 #14
0
파일: Program.cs 프로젝트: aeo24/WoWMap
        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));
        }
예제 #15
0
파일: TileBuilder.cs 프로젝트: aeo24/WoWMap
        public byte[] Build()
        {
            Geometry = new Geometry.Geometry {Transform = true };
            {
                var main = new ADT(World, X, Y);
                main.Read();
               // main.Generate();
                Geometry.AddADT(main);
            }

            if (Geometry.Vertices.Count == 0 && Geometry.Indices.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(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.SaveWavefrontObject($"{World}_{X}_{Y}.obj");
            Geometry.Indices.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.MarkWalkableTriangles(Config.WalkableSlopeAngle, ref vertices, ref triangles,out areas);
          //  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 connections = new List<OffMeshConnection>();


            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();
            GC.Collect();
            return tileData;
        }
예제 #16
0
 public void Merge(ADT adt, Chunk chunk)
 {
     ADT = adt;
     Read(new ChunkData(chunk.GetStream(), chunk.Size));
 }