Menu

Welcome, Guest. Please login or register.
May 20, 2019, 05:28:38 pm

Login with username, password and session length

Author Topic: [ADT] Map reversed [Solved]  (Read 217 times)

Unbreakables

  • Registred Member
  • GM Isle Explorer
  • *****
  • Posts: 21
    • View Profile
[ADT] Map reversed [Solved]
« on: April 07, 2019, 03:01:00 pm »
Hi everyone !

I need some precisions on the chunk and tiles pattern. I followed these structure on the wiki :



And all tiles are rotated by 90° :


Something is wrong in the order... The MCNK position is the corner north-east of the tile ?
And if it is, it's the corner north-east on the MCVT ?




And the second mcnk is at the south or the west of the first ?

The wiki isn't really clear on these points.
« Last Edit: May 03, 2019, 07:52:28 pm by Unbreakables »

schlumpf

  • Administrator
  • Creator of Worlds
  • *****
  • Posts: 2961
    • View Profile
Re: [ADT] Map reversed
« Reply #1 on: April 07, 2019, 11:51:55 pm »
in map coordinates, the top left of an adt tile is on the north-west.

Unbreakables

  • Registred Member
  • GM Isle Explorer
  • *****
  • Posts: 21
    • View Profile
Re: [ADT] Map reversed
« Reply #2 on: April 08, 2019, 01:21:17 pm »
Okay, so the algorithm is wrong ? Because if you start from the top-left and draw the tile to the bottom-right, you must increase x and decrease y... Or the opengl axis are inversed ?

The wiki algorithm give map flipped on y (vertical) axis and tile rotated.
Code: [Select]
    gl.glVertex3f( y, x, nL1);
    gl.glVertex3f( y+1, x, nL2);
    gl.glVertex3f(y+0.5f, x+0.5f, L);


If you decrease x and y, tiles aren't rotated, but map still flipped on y.
Code: [Select]
gl.glVertex3f( y, x, nL1);
    gl.glVertex3f( y-1, x, nL2);
    gl.glVertex3f(y-0.5f, x-0.5f, L);




If you don't inverse y and x, and decrease both, map aren't flipped on y, but tiles are rotated...
Code: [Select]
    gl.glVertex3f( x, y, nL1);
    gl.glVertex3f( x, y+1, nL2);
    gl.glVertex3f(x+0.5f, y+0.5f, L);




I don't understand... If the position is the top-left, and the tile's height are stored like on the wiki (left to right, top to bottom), we should just draw it left to right (positive x) and top to bottom (negative y) no ?

I tried like this and tiles are rotated by 90° and the position isn't on the top-left but in the bottom-left... Like if the y axis was reversed...

I will become crazy.

schlumpf

  • Administrator
  • Creator of Worlds
  • *****
  • Posts: 2961
    • View Profile
Re: [ADT] Map reversed
« Reply #3 on: April 08, 2019, 09:17:57 pm »
Yeah, wow coordinate systems are a bitch. The ADT article has some ramblings on top that might help. Otherwise I suggest looking at existing software, a lot.

In this case i mostly suggest mirroring not on a per chunk drawing basis but one pushmatrix above. That way, not every single chunk is wrong but the entire terrain should be transformed ;)

Unbreakables

  • Registred Member
  • GM Isle Explorer
  • *****
  • Posts: 21
    • View Profile
Re: [ADT] Map reversed [Solved]
« Reply #4 on: May 03, 2019, 09:23:36 pm »
After a month of work... This works finally !



I publish my algorythm and some explanations just in case someone have the same problem.


Intro :

I decide to transform wow coordinates system (x axis to the north, y axis to the west) into classic coordinates system (x axis to the east, y axis to the north), because wow system have absolutely no sense.
I use an algorythm working with GL_TRIANGLES rendering option.


Theory :

I will consider that you already know all informations on the wiki.

The wow coordinates system is rotated by 90° to the left compared to the classic system.


Each MCNK have a grid like this :


In the classic system :


I arbitrarily choice to name triangle with letters and vertrices with number like this :


I will name this 5 vertices group "square-crossed" in the next of this post.


Algorythm :

All things below need to be done for each of the 256 MCNK.

Code: [Select]
for (int i = 0; i < 256; i++) // For every mcnk chunk
{
}

First, we need the transform the ADT position into the classic system. The transformation is like this :
Code: [Select]
wow -> classic
x -> y
y -> -x

Code: [Select]
Vector3f ADT_MCNK::GetPosition()
{
Vector3f pos(-m_header.posy, m_header.posx, m_header.posz);
return pos;
}

For each of 64 (8x8) square-crossed, we need to get height value of the vertices.

Code: [Select]
for (int i = 0; i < 256; i++) // For every mcnk chunk
{
Vector3f pos = m_mcnk[i].GetPosition();

for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
{
// Get heights
}
}
}



On the image above :
height 1 (H1) have the "coordinate" (x, y)
H2 => (x+1, y)
H3 => (x+1, y+1)
H4 => (x, y+1)

Example, with x = y = 0 (on the first vertex) :
H1 => (0,0)
H2 => (1,0)
H3 => (1,1)
H4 => (0,1)

H5 will just use (x,y).

H1-4 are for corners vertices, H5 is for center vertex.

The array with all height have only one dimension, so we need to make two functions returning the number of the cell in the array in function of x and y. (If you work in C++, don't forget array begins at 0)

Code: [Select]
int ADT_MCNK::GetIdNoLOD(int x, int y)
{
return x + y * 17;
}

int ADT_MCNK::GetIdLOD(int x, int y)
{
return 9 + x + y * 17;
}

And two function returning the height value.

Code: [Select]
float ADT_MCNK::GetValNoLOD(int x, int y)
{
return m_mcvt.height[GetIdNoLOD(x, y)];
}

float ADT_MCNK::GetValLOD(int x, int y)
{
return  m_mcvt.height[GetIdLOD(x, y)];
}

Code: [Select]
for (int i = 0; i < 256; i++) // For every mcnk chunk
{
Vector3f pos = m_mcnk[i].GetPosition();

for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
{
float h1 = m_mcnk[i].GetValNoLOD(x, y);
float h2 = m_mcnk[i].GetValNoLOD(x+1, y);
float h3 = m_mcnk[i].GetValNoLOD(x+1, y+1);
float h4 = m_mcnk[i].GetValNoLOD(x, y+1);
float h5 = m_mcnk[i].GetValLOD(x, y);
}
}
}

Now it's near finished, you just need to generate vertices coordinates of the 4 triangles (I chose to store vertices into a array). Don't forget to set the scale between vertices (scale = 4.1666625). And don't forget the grid is drawn to the left and to the bottom (x positive and y negative).

The general coordinates is like this :
(pos.x + x * scale, pos.y - y * scale, pos.z + height)

Code: [Select]
for (int i = 0; i < 256; i++) // For every mcnk chunk
{
Vector3f pos = m_mcnk[i].GetPosition();

for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
{
float h1 = m_mcnk[i].GetValNoLOD(x, y);
float h2 = m_mcnk[i].GetValNoLOD(x+1, y);
float h3 = m_mcnk[i].GetValNoLOD(x+1, y+1);
float h4 = m_mcnk[i].GetValNoLOD(x, y+1);
float h5 = m_mcnk[i].GetValLOD(x, y);

// Tri A
AddVertices(pos.x + (x)*scale, pos.y - (y)*scale, pos.z + h1);               // H1
AddVertices(pos.x + (x+1)*scale, pos.y - (y)*scale, pos.z + h2);             // H2
AddVertices(pos.x + (x + 0.5f)*scale, pos.y - (y + 0.5f)*scale, pos.z + h5); // H5

// Tri B
AddVertices(pos.x + (x+1)*scale, pos.y - (y)*scale, pos.z + h2);             // H2
AddVertices(pos.x + (x+1)*scale, pos.y - (y + 1)*scale, pos.z + h3);         // H3
AddVertices(pos.x + (x + 0.5f)*scale, pos.y - (y + 0.5f)*scale, pos.z + h5); // H5

// Tri C
AddVertices(pos.x + (x+1)*scale, pos.y - (y + 1)*scale, pos.z + h3);         // H3
AddVertices(pos.x + (x)*scale, pos.y - (y + 1)*scale, pos.z + h4);           // H4
AddVertices(pos.x + (x + 0.5f)*scale, pos.y - (y + 0.5f)*scale, pos.z + h5); // H5

// Tri D
AddVertices(pos.x + (x)*scale, pos.y - (y + 1)*scale, pos.z + h4);           // H4
AddVertices(pos.x + (x)*scale, pos.y - (y)*scale, pos.z + h1);               // H1
AddVertices(pos.x + (x + 0.5f)*scale, pos.y - (y + 0.5f)*scale, pos.z + h5); // H5
}
}
}

Hope this could help you and you enjoy my paint art. Apologize my poor english, I'm french native. Thanks schlumpf again a lot for your help ! If I finished my project one day, you will be in the credits.
« Last Edit: May 03, 2019, 11:54:07 pm by Unbreakables »

schlumpf

  • Administrator
  • Creator of Worlds
  • *****
  • Posts: 2961
    • View Profile
Re: [ADT] Map reversed [Solved]
« Reply #5 on: May 03, 2019, 11:26:09 pm »
Wow. I did not expect such wall of text. Congratulations on making it!

You may even want to add that to the talk page on wiki.

One thing to change maybe is that there isn't really "lod" and "no lod", that's just what some very early reverse engineer thought. WoW always uses all vertices.

Unbreakables

  • Registred Member
  • GM Isle Explorer
  • *****
  • Posts: 21
    • View Profile
Re: [ADT] Map reversed [Solved]
« Reply #6 on: May 03, 2019, 11:47:55 pm »
Thanks !

I will put it on wiki latter, if you think it's useful^^

Yes, I just keep the name on the wiki to distinguish corners and center vertices. I will change it to name more appropriate.