Structure of MH2O chunk menu

Shout-Out

User Tag List

Results 1 to 2 of 2
  1. #1
    Bananenbrot's Avatar Contributor
    Reputation
    153
    Join Date
    Nov 2009
    Posts
    384
    Thanks G/R
    1/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Structure of MH2O chunk

    Hi there,
    I'm currently working out a pathfinding system for my bot... so excuse my ignorance considering modelediting and .mpqs^^
    I follow the blog of dejavu11 (well known as MPQNav). Like probably many others, I realized the heavily change to the MCLQ chunk so I tried to extract it for myself (wow). The problem is, that the WoWDev is very short and not really precise on conveying data order. That's where I need help, as far as I understand, the MH2O chunk looks something like this:

    Code:
    (MH2O 8 byte header)
    Header
    HeaderChunk[0]
    HeaderChunk[1]
    ...
    HeaderChunk[255]
    And that's the point: Is it true, that the Header sub-chunks are ordered this way (sequental, index++ like)? If not, how?

    Anyways, then there are the information chunks, each mapped to a HeaderChunk from where you could find them via the ofs.Information offset.
    Are these chunks packed straight after another? So I could readout the first Info chunk, then the 2nd... , rather then using the offset for each chunk, i.e.:

    Code:
    Information[0](8 Byte Header) <---- *HeaderChunk[0].ofsInformation
    Information[0]
    
    ...(some data) // Or are they followed each after another?
    
    Information[1](8 Byte Header) <---- *HeaderChunk[1].ofsInformation
    Information[1]
    
    ...(some data)
    
    ......(so on)
    
    Information[255](8 Byte Header) <---- *HeaderChunk[255].ofsInformation
    Information[255]
    The 3rd and last Data chunk is the "Data" chunk, which consists only of the HeightMap chunks... they are clearly mapped to their related Information chunks so it's not really a problem to figure out. But here again the same question: Do I have to read them all via offset or can I read index for index while only jumping to the first chunk (via offset)?

    Hope this also helps the 00berL3echers like me who are constantly hitting the search button hundredfold a day...

    EDIT: Ok.. got it right for now
    Last edited by Bananenbrot; 12-24-2009 at 07:12 AM.

    Structure of MH2O chunk
  2. #2
    Bananenbrot's Avatar Contributor
    Reputation
    153
    Join Date
    Nov 2009
    Posts
    384
    Thanks G/R
    1/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Because I got a PM of a user and still not able to PM him back (10 Post rule olol)... Here is my answer:
    Greetings.

    I am also parsing terrain data, and I'm curious..

    Did you get MH2O working completely?

    I'm having a bit of difficulty determining when to use which render mask. Any thoughts?
    Yeah i got it, it's not as hard as I thought... the render mask is a byte array of 64 bitflags (-> 8 bytes). You might know that they determine if to render water in one of the 64 tiles (9x9 vertices with 8x8 tiles between). So all you need to do is to only override the green terrain vertices if the render flag says so. If it is the case, you have to get the corresponding water height of the heightmap (64 floats for each tile iirc) and then override the vertices in the corners of the tile (NW, NE, SW, SE). I got solved that like this:

    Code:
    for(int row = 0; row < 8; row++)
    {
        for(int col = 0; col < 8; col++)
        {
            if((render[row] & 1 << (7-col)) != 0)
            {
                VertexPositionColor NW = positionList[row * 9 + col];     // Get currentMCNK vertex, there are 9 per row
                NW.Color = Color.Blue;
                // But there are only 8 floats per row for each tile in between the vertices
                NW.Position.Z = heightmap[row * 8 + col];    // Z is up for me, in MPQNav it's Y
                positionList[row * 9 + col] = NW;
               
                VertexPositionColor NE = positionList[row * 9 + col + 1];
                NE.Color = Color.Blue;
                NE.Position.Z = heightmap[row * 8 + col];
                positionList[row * 9 + col + 1] = NE;
    
                // continue for SW and SE with (row+1)*8
            }
        }
    }
    In my own code, I only iterate from xOffset to xOffset + width in col and from yOffset to yOffset + height in rows from the MH2OInfo chunk. Sometimes it looks a bit awkward, with edged rivers and so on, bur for now... it's enough for me^^ to be continued :P
    P.S.: try the SVN on the MPQNav blog, it's an updated version, I'm currently learning form it...

    EDIT: As I refactored my own project and compared with the "real" MPQNav, I found out that the bitflags are not always present. There are only MH2OInfo.height bytes in that array, you have to either fill the rest with 0x00 or care for that in my given code. You got wrong data because you maybe read to far and got into the heightmap part ( they follow each after another, test it with breakpoints and test the difference of MH2OInfo.ofsHeightMap and MH2OInfo.ofsMask2). It may confuse you even more to read that... I'm just about to figure it out, so pm me/post here if you want to know it

    EDIT2: Ok, in MPQNav the MH2OInfo.ofsMask2 is dereferenced for getting to the bit mask. That's much more work than only use MH2OHeader.Render, which points to an 8-byte array. If it does not, (if(MH2OHeader.Render == 0)), you may render the whole mcnk with water(resulting in an 8 byte array bit 0xFF elements). The same goes for a bit mask with only 0x00 if the MH2OInfo.width or MH2OInfo.height not 0:
    Code:
     if(RenderMask.All(b => b == 0) && ((MH2OInfo.width != 0) || (MH2OInfo.height != 0))) )
    which is interpreted same as a Mask for a missing MH2OHeader.Render offset.
    Something similar happens to the HeightMap. There are always only as much values given as needed for the liquid rectangle(MH2OInfo.yOffset, .xOffset, height, width). So you only get an array of HeightMap[height+1][width+1] (for a 4*3 rect you need 5*4 vertices). You need to care for special cases (such as MH2OInfo.ofsHeightMap == 0 and so on, similar to the rendermask) explained in the WoWDev article below.
    Hope you understood, but don't think so
    take WoWDev as reference, the explanation helped me a lot:
    http://www.madx.dk/wowdev/wiki/index..._Header.Render

    One thing for when you got it: It really does not look that much pretty for me... rather it seems that the green "islands" and stripes in the liquids are places, where you are actually in a liquid, but still remain walkable. The result are blue patches spread along an ingame river or a shallow water.
    Last edited by Bananenbrot; 01-07-2010 at 10:52 AM.

Similar Threads

  1. Basic Introduction to the structure of WoW's files and hexediting
    By schlumpf in forum WoW ME Tools & Guides
    Replies: 11
    Last Post: 04-12-2008, 12:47 PM
  2. [Question] M2 Structure question?
    By houseplant2 in forum WoW ME Questions and Requests
    Replies: 1
    Last Post: 01-06-2008, 07:09 AM
  3. WotLK's New MPQ Structure
    By merfed in forum World of Warcraft Model Editing
    Replies: 19
    Last Post: 11-28-2007, 10:39 AM
  4. Database Structure Guide
    By merfed in forum WoW EMU Guides & Tutorials
    Replies: 5
    Last Post: 11-09-2007, 12:17 PM
All times are GMT -5. The time now is 08:51 PM. 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