Example #1
0
 /// <summary>
 /// Reads the JMXVNVM1000 file format and extract all the required
 /// </summary>
 private static void ReadJMXVNVM1000(string Filename, TerrainMesh Mesh)
 {
     using (var fs = new FileStream(Filename, FileMode.Open, FileAccess.Read))
     {
         using (var br = new BinaryReader(fs))
         {
             // Header
             br.SkipRead(12);
             // Navigation Entries
             ushort entryCount = br.ReadUInt16();
             for (ushort i = 0; i < entryCount; i++)
             {
                 br.SkipRead(30);
                 br.SkipRead(br.ReadUInt16() * 6);
             }
             // Navigation Cells
             uint cellCount = br.ReadUInt32();
             br.SkipRead(4);
             for (uint i = 0; i < cellCount; i++)
             {
                 br.SkipRead(16);
                 br.SkipRead(br.ReadByte() * 2);
             }
             // Navigation Region Links
             br.SkipRead(br.ReadUInt32() * 27);
             // Navigation Cell Links
             br.SkipRead(br.ReadUInt32() * 23);
             // Texture Map
             br.SkipRead(96 * 96 * 8);
             // Height Map
             Mesh.Width = Mesh.Height = 97;
             for (int y = 0; y < 97; y++)
             {
                 for (int x = 0; x < 97; x++)
                 {
                     Mesh.Vertices.Add(new Vector3()
                     {
                         X = x * 20 + Mesh.OffsetPosX * 1920, Y = y * 20 + Mesh.OffsetPosY * 1920, Z = br.ReadSingle()
                     });
                 }
             }
             // Just skip everything else
             // br.SkipRead(36);
             // br.SkipRead(36 * 4);
         }
     }
 }
Example #2
0
        /// <summary>
        /// Application entry point
        /// </summary>
        static async Task Main(string[] args)
        {
            List <TerrainMesh> terrains = new List <TerrainMesh>();

            // Load files to convert
            string[] filenames = args;
            if (filenames.Length == 0)
            {
                // Find all .nvm files inside current folder
                filenames = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.nvm");
            }

            // Loading terrain
            foreach (var path in filenames)
            {
                Console.WriteLine("Loading " + path);
                var filename = Path.GetFileName(path);

                // Gets the tile map (X,Y) from Region Id
                var match = Regex.Match(filename, "([0-9a-zA-Z]{2})([0-9a-zA-Z]{2}).nvm$");
                if (!match.Success)
                {
                    Console.WriteLine("Error: Region offset cannot be extracted from filename, the terrain won't be extracted [" + filename + "]");
                    continue;
                }

                // Filling some mesh info
                TerrainMesh mesh = new TerrainMesh();
                mesh.Name       = filename;
                mesh.OffsetPosY = int.Parse(match.Groups[1].Value, System.Globalization.NumberStyles.HexNumber);
                mesh.OffsetPosX = int.Parse(match.Groups[2].Value, System.Globalization.NumberStyles.HexNumber);

                // Try to read all vertices from the file
                try
                {
                    ReadJMXVNVM1000(path, mesh);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: " + ex);
                    continue;
                }

                // Build triangles from vertices like quads/2
                var w = mesh.Width - 1;
                var h = mesh.Height - 1;
                for (int i = 0; i < h; i++)
                {
                    for (int j = 0; j < w; j++)
                    {
                        uint a = (uint)((i * mesh.Width) + j);
                        uint b = a + 1u;
                        uint c = (uint)(a + mesh.Width);
                        mesh.Triangles.Add(new uint[] { a, b, c });
                        mesh.Triangles.Add(new uint[] { b, c, c + 1u });
                    }
                }

                // Add generated mesh
                terrains.Add(mesh);
            }

            // Avoid saving an empty terrain
            if (terrains.Count == 0)
            {
                Console.WriteLine("Error: Not enough .nvm files to create terrain!");
                return;
            }

            Console.WriteLine("Generating \"Terraing.obj\"...");
            // Make sure the printing format will be right
            var en_us = new System.Globalization.CultureInfo("en-us");

            using (var fs = new FileStream("Terrain.obj", FileMode.Create, FileAccess.Write))
            {
                // Generating as a whole object
                var buffer = System.Text.Encoding.ASCII.GetBytes("o Terrain" + Environment.NewLine);
                await fs.WriteAsync(buffer, 0, buffer.Length);

                uint size = 1;
                // Apply terrain center
                foreach (var mesh in terrains)
                {
                    // Just writes an endline
                    buffer = System.Text.Encoding.ASCII.GetBytes(Environment.NewLine);
                    await fs.WriteAsync(buffer, 0, buffer.Length);

                    // Writing mesh as group
                    buffer = System.Text.Encoding.ASCII.GetBytes($"g {mesh.Name}_{mesh.OffsetPosY}x{mesh.OffsetPosX}" + Environment.NewLine);
                    await fs.WriteAsync(buffer, 0, buffer.Length);

                    foreach (var v in mesh.Vertices)
                    {
                        buffer = System.Text.Encoding.ASCII.GetBytes(string.Format(en_us, "v {0} {1} {2}{3}", v.X, v.Y, v.Z, Environment.NewLine));
                        await fs.WriteAsync(buffer, 0, buffer.Length);
                    }
                    foreach (var t in mesh.Triangles)
                    {
                        buffer = System.Text.Encoding.ASCII.GetBytes($"f {t[0] + size} {t[1] + size} {t[2] + size}" + Environment.NewLine);
                        await fs.WriteAsync(buffer, 0, buffer.Length);
                    }
                    size += (uint)(mesh.Height * mesh.Width);
                }
                // Just to know it finishes
                Console.WriteLine("\"Terraing.obj\" created successfully!");
            }
        }