Converting coordinates ADT / M2 menu

Shout-Out

User Tag List

Results 1 to 4 of 4
  1. #1
    mazer's Avatar Active Member
    Reputation
    55
    Join Date
    Sep 2007
    Posts
    87
    Thanks G/R
    11/27
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Converting coordinates ADT / M2

    Hi folks,

    currently working on some basic visualisation stuff (no, not reinventing recast / detour)
    as you can see i am trying to assemble the terrain and the models.

    i used wow.export to export the adt and m2 as obj for convenience.
    reading file after file and merging into a new obj while reading the ModelPlacementInformation.csv for the models.

    while looking on github and wowdev, i noticed that the cooridnates for the models have to be adjusted to x, z, -y
    but even after adjusting, the models are way off.

    the code in question (adding the model vertices to the terrain):
    Code:
    float x = float.Parse(parts[1], CultureInfo.InvariantCulture);
    float y = float.Parse(parts[2], CultureInfo.InvariantCulture);
    float z = float.Parse(parts[3], CultureInfo.InvariantCulture);
    
    float finalX = placement.PositionX;
    float finalY = placement.PositionZ;
    float finalZ = -placement.PositionY;
    
    vertices.Add($"v {x + finalX} {y + finalY} {z + finalZ}");
    Full C# Code


    Screenshot 2025-01-05 021506.png

    Converting coordinates ADT / M2
  2. #2
    mazer's Avatar Active Member
    Reputation
    55
    Join Date
    Sep 2007
    Posts
    87
    Thanks G/R
    11/27
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    after looking at the code of the wow.export blender plugin and rewriting much of my code i am pretty close to finish.
    have to handle wmo groups, textures etc. but thats another story...

    using recast for display purpose:

    Screenshot 2025-01-05 200447.png


    working code, hacky & needs some love
    Code:
    using System;using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Globalization;
    
    
    namespace ObjMergerTool
    {
        public class ModelPlacement
        {
            public string ModelFile { get; set; }
            public float PositionX { get; set; }
            public float PositionY { get; set; }
            public float PositionZ { get; set; }
            public float RotationX { get; set; }
            public float RotationY { get; set; }
            public float RotationZ { get; set; }
            public float RotationW { get; set; }
            public float ScaleFactor { get; set; }
            public float FinalX { get; set; }
            public float FinalY { get; set; }
            public float FinalZ { get; set; }
    
    
            public void CalculateFinalPosition()
            {
                const float MAX_SIZE = 51200f / 3f;
                FinalX = MAX_SIZE - PositionX;
                FinalY = PositionY;
                FinalZ = MAX_SIZE - PositionZ;
            }
        }
    
    
        public class ObjMerger
        {
            private List<string> vertices = new List<string>();
            private List<string> faces = new List<string>();
            private int vertexOffset = 0;
            private int currentFileVertexCount = 0;
    
    
            public void MergeAllFiles(string[] objFiles, string baseDirectory)
            {
                vertices.Clear();
                faces.Clear();
                vertexOffset = 0;
    
    
                foreach (var fileInfo in objFiles.OrderBy(f => f))
                {
                    currentFileVertexCount = 0;
                    ProcessFile(fileInfo);
                    vertexOffset += currentFileVertexCount;
    
    
                    var csvFile = Path.ChangeExtension(fileInfo, null) + "_ModelPlacementInformation.csv";
                    if (File.Exists(csvFile))
                    {
                        ProcessPlacementFile(csvFile, baseDirectory);
                    }
                }
    
    
                WriteToFile(Path.Combine(baseDirectory, "merged_complete_with_placements.obj"));
            }
    
    
            private void ProcessFile(string fileName)
            {
                foreach (var line in File.ReadLines(fileName))
                {
                    if (string.IsNullOrWhiteSpace(line)) continue;
    
    
                    var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
    
    
                    if (parts[0] == "v")
                    {
                        currentFileVertexCount++;
                        vertices.Add(line);
                    }
                    else if (parts[0] == "f")
                    {
                        faces.Add("f " + string.Join(" ", parts.Skip(1).Select(i => (int.Parse(i.Split('/')[0]) + vertexOffset).ToString())));
                    }
                }
            }
    
    
            private void ProcessModelPlacement(string objFile, ModelPlacement placement)
            {
                foreach (var line in File.ReadLines(objFile))
                {
                    if (string.IsNullOrWhiteSpace(line)) continue;
    
    
                    var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
    
    
                    if (parts[0] == "v" && parts.Length >= 4)
                    {
                        currentFileVertexCount++;
                        float x = float.Parse(parts[1], CultureInfo.InvariantCulture) * placement.ScaleFactor + placement.FinalX;
                        float y = float.Parse(parts[2], CultureInfo.InvariantCulture) * placement.ScaleFactor + placement.FinalY;
                        float z = float.Parse(parts[3], CultureInfo.InvariantCulture) * placement.ScaleFactor + placement.FinalZ;
    
    
                        vertices.Add($"v {x.ToString(CultureInfo.InvariantCulture)} {y.ToString(CultureInfo.InvariantCulture)} {z.ToString(CultureInfo.InvariantCulture)}");
                    }
                    else if (parts[0] == "f")
                    {
                        faces.Add("f " + string.Join(" ", parts.Skip(1).Select(i => (int.Parse(i.Split('/')[0]) + vertexOffset).ToString())));
                    }
                }
            }
    
    
            private void ProcessPlacementFile(string csvPath, string baseDirectory)
            {
                var lines = File.ReadAllLines(csvPath);
                if (lines.Length <= 1) return;
    
    
                for (int i = 1; i < lines.Length; i++)
                {
                    if (string.IsNullOrWhiteSpace(lines[i])) continue;
    
    
                    var values = lines[i].Split(';');
                    if (values.Length < 9) continue;
    
    
                    var placement = new ModelPlacement();
                    try
                    {
                        placement.ModelFile = values[0];
                        placement.PositionX = float.Parse(values[1].Replace(",", "."), CultureInfo.InvariantCulture);
                        placement.PositionY = float.Parse(values[2].Replace(",", "."), CultureInfo.InvariantCulture);
                        placement.PositionZ = float.Parse(values[3].Replace(",", "."), CultureInfo.InvariantCulture);
                        placement.RotationX = !string.IsNullOrEmpty(values[4]) ? float.Parse(values[4].Replace(",", "."), CultureInfo.InvariantCulture) : 0f;
                        placement.RotationY = !string.IsNullOrEmpty(values[5]) ? float.Parse(values[5].Replace(",", "."), CultureInfo.InvariantCulture) : 0f;
                        placement.RotationZ = !string.IsNullOrEmpty(values[6]) ? float.Parse(values[6].Replace(",", "."), CultureInfo.InvariantCulture) : 0f;
                        placement.RotationW = !string.IsNullOrEmpty(values[7]) ? float.Parse(values[7].Replace(",", "."), CultureInfo.InvariantCulture) : 0f;
                        placement.ScaleFactor = !string.IsNullOrEmpty(values[8]) ? float.Parse(values[8].Replace(",", "."), CultureInfo.InvariantCulture) : 1f;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Fehler beim Parsen der Zeile: {lines[i]}");
                        Console.WriteLine($"Exception: {ex.Message}");
                        continue;
                    }
    
    
                    placement.CalculateFinalPosition();
    
    
                    string modelPath = placement.ModelFile;
                    if (modelPath.StartsWith("..\\"))
                    {
                        var baseDir = Directory.GetParent(baseDirectory).Parent.FullName;
                        modelPath = modelPath.Replace("..\\..\\", "").Replace(".m2", ".obj");
                        modelPath = Path.Combine(baseDir, modelPath);
    
    
                        if (File.Exists(modelPath))
                        {
                            Console.WriteLine($"Platziere Model: {modelPath}");
                            currentFileVertexCount = 0;
                            ProcessModelPlacement(modelPath, placement);
                            vertexOffset += currentFileVertexCount;
                        }
                        else
                        {
                            Console.WriteLine($"Model nicht gefunden: {modelPath}");
                        }
                    }
                }
            }
    
    
            private void WriteToFile(string outputPath)
            {
                using (var writer = new StreamWriter(outputPath))
                {
                    writer.WriteLine("# Merged OBJ File");
                    writer.WriteLine($"# Vertices: {vertices.Count}, Faces: {faces.Count}");
    
    
                    foreach (var vertex in vertices)
                        writer.WriteLine(vertex);
    
    
                    foreach (var face in faces)
                        writer.WriteLine(face);
                }
            }
        }
    
    
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    Console.Write("Basis-Verzeichnis eingeben: ");
                    string baseDirectory = Console.ReadLine().Trim();
                    var files = Directory.GetFiles(baseDirectory, "adt_*.obj", SearchOption.TopDirectoryOnly);
                    Console.WriteLine($"Gefunden: {files.Length} OBJ-Dateien");
    
    
                    new ObjMerger().MergeAllFiles(files, baseDirectory);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"FEHLER: {ex.Message}");
                    Console.WriteLine($"StackTrace: {ex.StackTrace}");
                }
    
    
                Console.WriteLine("\nTaste drücken zum Beenden...");
                Console.ReadKey();
            }
        }
    }

  3. #3
    namreeb's Avatar Legendary

    Reputation
    668
    Join Date
    Sep 2008
    Posts
    1,029
    Thanks G/R
    8/222
    Trade Feedback
    0 (0%)
    Mentioned
    9 Post(s)
    Tagged
    0 Thread(s)

  4. #4
    MrFade's Avatar Contributor CoreCoins Purchaser
    Reputation
    102
    Join Date
    Aug 2015
    Posts
    153
    Thanks G/R
    41/64
    Trade Feedback
    2 (100%)
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Don't mean to steal the thread But was working on a mesh extractor as well a bit ago and gave up after I could not figure out why my meshes would would have holes in the water line :

    image.png

    image (1).png

    I get that hole right after the triangle rasterization, the polys are all correctly marked for liquids as well :/

Similar Threads

  1. [Question] Convert 3ds to M2
    By Allifeur in forum WoW ME Questions and Requests
    Replies: 2
    Last Post: 01-14-2013, 05:35 PM
  2. Convert coordinates from memory to ingame coordinates?
    By radarlove in forum WoW Memory Editing
    Replies: 10
    Last Post: 10-19-2012, 08:36 PM
  3. [Question] Convert TBC ADT's to WotLK ADT's
    By Nadromar in forum WoW ME Questions and Requests
    Replies: 2
    Last Post: 06-30-2012, 08:40 AM
  4. [HowTo] Convert MDX to M2
    By Tigurius in forum WoW ME Tools & Guides
    Replies: 6
    Last Post: 05-07-2010, 05:31 AM
  5. Possible Theroy on how to convert .wmo to .m2/guide on how to.
    By Shattered in forum World of Warcraft Model Editing
    Replies: 3
    Last Post: 02-17-2007, 08:41 PM
All times are GMT -5. The time now is 06:39 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search