# Forum > World of Warcraft > World of Warcraft Bots and Programs > WoW Memory Editing >  [Tool] Navmesh Creator

## sPeC!

It seems there are a lot of people trying to get navmesh data from wow maps without success.

I have been working on bot project for myself and a few others that may be interested, i will create a thread about that later when i have some time.

Anyway part of this project is the navmesh navigation, so i decided to give something back to the mmowned.com community, since i have already taken so much on the form of knowledge.
This is a simple tool it allows to extract navmesh data from given .adt files and save it in a format ready to be imported by Detour (It's created/saved on tile based format). It can also output the mesh data into a .obj file.

You need to setup the WoW data folder on the setup.ini file before usage.
It can extract data based on a given path to a wdt, or a .cmp file that isn't more than a file with a list of ADT's. An example of .cmp file is given of the Ellwin Forest Zone.

It has limitation on how much info it can parse at a time, because it was designed to work in that way. So if you try to create data for the entire continent of Azeroth at one time it will most certainly die...

You will probably need to have .net v4 installed, i haven't tested this on any other computer than my own, so use at your own risk...

Main credits go to:
*Flowerew*: for WoWMapper that i used as base
*MaiN*: For helped me at start
*TOM_RUS and caytchen*: For the tips on the changes in patch 4.0
*memononen*: Recast and Detour

*Everyone else that keeps sharing info!*

Usage example:


Uploaded with ImageShack.us

VIRUS TOTAL REPORT

Download

Have fun,

----------


## Flowerew

This sure will help alot of people. Coincidence: I started updating and rewriting wowmapper for v4.0 today. +rep to you

----------


## CrimeTime

didnt work for me, i edited the ini file to my WoW path, and opend the Application and all what happens is that it close directly  :Smile:

----------


## sPeC!

> This sure will help alot of people. Coincidence: I started updating and rewriting wowmapper for v4.0 today. +rep to you


Cool you you did a good job with the first version, i am sure the second will come off even better  :Smile:  i suppose you already noticed what the differences are on the new format, if you need something on it just beep, i will gladly help if i can.




> didnt work for me, i edited the ini file to my WoW path, and opend the Application and all what happens is that it close directly


Check the screenshot. It's a command line based tool  :Wink: 

Cheers,

----------


## CrimeTime

yes sure, but how to put a command in it when it closes directly? 
what i need to put in it? then can i make a *.bat for it.

----------


## sPeC!

> yes sure, but how to put a command in it when it closes directly? 
> what i need to put in it? then can i make a *.bat for it.


Well you can open a command line window and execute it from there, or yes you can create a batch file with the command inside.

Cheers,

----------


## CrimeTime

here for all other which got the same Problem like me:
run.bat


```
"MeshTool.exe" meshtool -c ElwyinnForest -o map.obj ellwindata.bin
```

----------


## sPeC!

> here for all other which got the same Problem like me:
> run.bat
> 
> 
> ```
> "MeshTool.exe" meshtool -c ElwyinnForest -o map.obj ellwindata.bin
> ```


Hehe actually there is a meshtool too much in there. I forgot people no long know how to execute a app from a command line.. That remembers me that i am getting old :/
I uploaded a new version with a batch file included...

Cheers,

----------


## miceiken

```
cmd.exe
cd C:\dir\to\the\app
MeshTool.exe -c ElwyinnForest -o map.obj ellwindata.bin
```

 :Smile: 

You could probably just add a Console.ReadKey(); (if in C# ofc, dont know about other languages), and the window will stay open until you press a key.

----------


## Tanaris4

Great work - any plans to release the source for it? Would love to create something simliar on OS X

----------


## namreeb

Glad to see more people taking an interest in proper navigation. +rep

----------


## sPeC!

> You could probably just add a Console.ReadKey(); (if in C# ofc, dont know about other languages), and the window will stay open until you press a key.


Done  :Smile: 




> Great work - any plans to release the source for it? Would love to create something simliar on OS X


Not really... Although there is lot of code, most is from recast and a bunch refactored from WoWMapper with 4.0 support. If you have any doubts on it i can offcourse try to help...



> Glad to see more people taking an interest in proper navigation. +rep


Yeah well i still have you Navigation System design process thread on my bookmarks  :Wink:  Unfortunately i never got to implement something that advanced..  :Wink: 

There are several people PM'ing me, asking how i found what adt's belong to a given zone, well, i have been using the database from the tool WoWMapEditor. But it shouldn't be that hard to make a custom parser and get updated/custom info...
If someone else have those kind of questions, please place them here at the thread so that i don't get repeated questions and consequently give repeated answers  :Smile: 

Cheers,

----------


## caytchen

Just remember you're probably reading the new Cataclysm map data. The old world may be found in OldWorld.mpq, but reading it can be a mess since some of it is in the split format (with the object references and texture data in single files) and other parts still have them in the ADT itself.

----------


## sPeC!

Oh.. Thanks for the info caytchen. Yes it's reading the new Cataclysm map data. But i wasn't aware that some of the parts were on the old format.. Every part that i tried was on the new split format. Anyway if someone has problems with it, they now already know what is causing it.. Unfortunately i won't have time to check/repair it that soon :/

Cheers,

----------


## caytchen

> Oh.. Thanks for the info caytchen. Yes it's reading the new Cataclysm map data. But i wasn't aware that some of the parts were on the old format.. Every part that i tried was on the new split format. Anyway if someone has problems with it, they now already know what is causing it.. Unfortunately i won't have time to check/repair it that soon :/
> 
> Cheers,


Don't worry, the new Cataclysm data has the new format throughout. Its just the old world that they have stuffed away in OldWorld where it's split.

----------


## sPeC!

> Hello sPeC,
> 
> I had seen you Post about the Meshcreator. Now my question is how do you formated the mesh??It isn't like the Sampel Safe Funktion.... Thank you Verry much!


Ok, i forgot to say on what Detour format the navmesh was being created/saved. It's created on tile based format.

Cheers,

----------


## telcy007

hi sPeC!
i've meshed the durotar map with your tool. but the problem is, that this tool cant mesh the part World\maps\Kalimdor\Kalimdor_40_32. I think, its some of the old world. Can you help me or modify the code to solve the problem  :Smile:  ? thank you

----------


## Flowerew

> hi sPeC!
> i've meshed the durotar map with your tool. but the problem is, that this tool cant mesh the part World\maps\Kalimdor\Kalimdor_40_32. I think, its some of the old world. Can you help me or modify the code to solve the problem  ? thank you


Actually its not the old format, but in sPeC's defence: he is dealing with alot of crap in the old version of wowmapper. Progress on updating wowmapper to WoW v4.0 is good. I spent two days beside work and it's almost usable again. telcy: see this screen http://i53.tinypic.com/vammd.png where you can see Kalimdor_40_32. I hope I can release it by the end of the week. This time I will also try to include more samples, like displaying the terrain with Direct3D, generating navmeshes, etc. Cheers

----------


## sPeC!

> hi sPeC!
> i've meshed the durotar map with your tool. but the problem is, that this tool cant mesh the part World\maps\Kalimdor\Kalimdor_40_32. I think, its some of the old world. Can you help me or modify the code to solve the problem ? thank you


I'am sorry telcy007, i currently don't have enough time to look into it because mid-term exams at school have started and have a bunch of school projects to do.. The good news are that Flowerew is updating his tool that is the main engine of this one, and it seems it will do what this one does but better...




> Actually its not the old format, but in sPeC's defence: he is dealing with alot of crap in the old version of wowmapper. Progress on updating wowmapper to WoW v4.0 is good. I spent two days beside work and it's almost usable again. telcy: see this screen http://i53.tinypic.com/vammd.png where you can see Kalimdor_40_32. I hope I can release it by the end of the week. This time I will also try to include more samples, like displaying the terrain with Direct3D, generating navmeshes, etc. Cheers


It's looking great! Keep the good job.

Cheers,

----------


## Flowerew

Just a little update for you guys: I commited my current progress. It's no public release yet (hence no download), but it is able to parse kalimdor/azeroth new/old ...that's what I tested so far. WMO interior is not yet included either, but for testing purposes it's enough to get going with the new format. A sample is included which requires SDL and the DirectX SDK, it will display the geometry for a given area id (12 for Elwynn Forest for example). I will create a new thread when it's ready for the public which should be by the end of the week (I really try). Here's a screen of the current sample: http://img607.imageshack.us/img607/2556/wowmapper01.png Cheers

----------


## RivaLfr

Very Good Job! +rep

----------


## TOM_RUS

> Just a little update for you guys: I commited my current progress. It's no public release yet (hence no download), but it is able to parse kalimdor/azeroth new/old ...that's what I tested so far. WMO interior is not yet included either, but for testing purposes it's enough to get going with the new format. A sample is included which requires SDL and the DirectX SDK, it will display the geometry for a given area id (12 for Elwynn Forest for example). I will create a new thread when it's ready for the public which should be by the end of the week (I really try). Here's a screen of the current sample: http://img607.imageshack.us/img607/2556/wowmapper01.png Cheers


How do you even able to open 4.x mpq's with libmpq? And what about patch files (wow-update-XXXXX.mpq), i'm pretty sure libmpq doesn't support this...

----------


## Flowerew

I haven't had no problems so far. Listfiles seem to be ok, and even expansion3.mpq has been read without problems. Same goes for wow-update-xxxxx.mpq, so I dont know what you mean, TOM_RUS.

----------


## TOM_RUS

> I haven't had no problems so far. Listfiles seem to be ok, and even expansion3.mpq has been read without problems. So I dont know what you mean, TOM_RUS.


Basicaly libmpq has no support for mpq files used in 4.x wow client. For example wow-update-XXXXX.mpq doesn't store any directly usable data, only diffs from base mpq+all previous diffs (PTCH files). I'm surprised that libmpq can still open thise new files...

P.S. While trying to get your sample running, i've encountered few problems: 2 compile errors in VS2010 and 1 crash, what i've modified so far to fix them:


```
Index: samples/Sample_D3dByAreaId.cpp
===================================================================
--- samples/Sample_D3dByAreaId.cpp	(revision 44)
+++ samples/Sample_D3dByAreaId.cpp	(working copy)
@@ -25,12 +25,12 @@
 
 //------------------------------------------------------------------------------
 int main( int arch, char **argv ) {
-  MpqHandler mpq_h( "C:\\Users\\Public\\Games\\World of Warcraft\\Data" );
+  MpqHandler mpq_h( "G:\\Games\\World of Warcraft\\Data" );
   loadAllMpqs( mpq_h );
 
   // load WDT file which tells us what ADT tiles to load
   BufferS_t file_buffer;
-  std::string zone_path( "oldworld\\world\\maps\\azeroth\\azeroth" );
+  std::string zone_path( "world\\maps\\azeroth\\azeroth" );
   mpq_h.getFile( zone_path + ".wdt", &file_buffer );
 
   // create geometry buffer
@@ -199,7 +199,7 @@
 
       // unique identifier not found: insert UID in map
       if ( found == uid_map.end() ) {
-        uid_map.insert( UidMap_t::value_type( doodad.info.uid, 0 ) );
+        uid_map.insert( UidMap_t::value_type( doodad.info.uid, (void*)0 ) );
 
         BufferS_t doodad_buf;
         mpq_h.getFile( doodad.name, &doodad_buf );
@@ -239,7 +239,7 @@
 
       // same procedure as above
       if ( found == uid_map.end() ) {
-        uid_map.insert( UidMap_t::value_type( wmo.info.uid, 0 ) );
+        uid_map.insert( UidMap_t::value_type( wmo.info.uid, (void*)0 ) );
 
         BufferS_t wmo_buf;
         mpq_h.getFile( wmo.name, &wmo_buf );
Index: src/wmomodel.cpp
===================================================================
--- src/wmomodel.cpp	(revision 44)
+++ src/wmomodel.cpp	(working copy)
@@ -83,8 +83,10 @@
 
   // read MODN chunk: doodad names
   i_str.read( (char*)&_modnChunk, CHUNK_DATA );
-  _modnChunk.doodadNames.resize( _modnChunk.size );
-  i_str.read( (char*)&_modnChunk.doodadNames[0], _modnChunk.size );
+  if(_modnChunk.size) {
+    _modnChunk.doodadNames.resize( _modnChunk.size );
+    i_str.read( (char*)&_modnChunk.doodadNames[0], _modnChunk.size );
+  }
 
   // read MODD chunk: doodad informations
   i_str.read( (char*)&_moddChunk, CHUNK_DATA );
```

and even after those fixes I can't get anything like displayed on your screenshot...
That's what I got http://img88.imageshack.us/img88/1808/elwynnforest.jpg

----------


## mindwalkr

What tool are people using to extract ADT's from the MPQ ? I tried MPQEditor and it extracted "successfully" (I have files full of data), but I can't seem to read the header successfully. Basically, the MH2O offset is zero. Ideas ?

----------


## namreeb

I believe the MH20 chunk is optional. That is, it's not present in ADT chunks which do not have MH2O water.

----------


## Flowerew

> Basicaly libmpq has no support for mpq files used in 4.x wow client. For example wow-update-XXXXX.mpq doesn't store any directly usable data, only diffs from base mpq+all previous diffs (PTCH files). I'm surprised that libmpq can still open thise new files...
> 
> P.S. While trying to get your sample running, i've encountered few problems: 2 compile errors in VS2010 and 1 crash, what i've modified so far to fix them:
> 
> 
> ```
> Index: samples/Sample_D3dByAreaId.cpp
> ===================================================================
> --- samples/Sample_D3dByAreaId.cpp	(revision 44)
> ...


Here's another screen of Orgrimmar: http://img340.imageshack.us/img340/7297/wowmapper02.png

Regarding your problem: It seems very strange, and I may have to get VS2010 to check it myself. Do you run 32 or 64 bit Windows? Have you had any hints as to when the crash occurs and why only 1 ADT seems to be displayed instead of a whole area? Any information would be greatly appreciated. Thanks for testing, TOM_RUS.

----------


## caytchen

> Basicaly libmpq has no support for mpq files used in 4.x wow client. For example wow-update-XXXXX.mpq doesn't store any directly usable data, only diffs from base mpq+all previous diffs (PTCH files). I'm surprised that libmpq can still open thise new files...


Do you even need them for this? I mean, I haven't really looked into them, but I guess the client will never process them itself - that would kill performance - but they're just input to the updater who will patch the respective MPQs.

----------


## _Mike

> Do you even need them for this? I mean, I haven't really looked into them, but I guess the client will never process them itself - that would kill performance - but they're just input to the updater who will patch the respective MPQs.


It does process them.
If you leave the launcher running after a patch it says "Applying non-critical updates" (or similar, don't remember the exact phrase) which creates new mpqs in <gamedir>\data\cache where all the diffs are applied. There's a bunch of patch-base-XXXX.mpq there.
If you start the game before the lancher is finished it will do the same when a 'needs to be patched' file is loaded.
So to be sure you're getting up-to-date data you should either use an mpq lib that can handle the diffs, or read from the cache dir. Though on a side note I haven't checked if there is any updated terrain in the patches since 4.0, but there will eventually.

----------


## TOM_RUS

> Here's another screen of Orgrimmar: http://img340.imageshack.us/img340/7297/wowmapper02.png
> 
> Regarding your problem: It seems very strange, and I may have to get VS2010 to check it myself. Do you run 32 or 64 bit Windows? Have you had any hints as to when the crash occurs and why only 1 ADT seems to be displayed instead of a whole area? Any information would be greatly appreciated. Thanks for testing, TOM_RUS.


I'm running WinXP SP3 32 bit + VS2010. The crash was when parsing some ADT with _modnChunk.size == 0. I have no idea why only 1 ADT displayed, may be it's somehow related to VS2010...

----------


## Megamike55

Just tested the pre-release, flow, and it works great. Exported all of Azeroth so far. Of course I'll do it again once you finish, because of the WMO interiors not being there, but still, thanks so much.
I wish I could rep you like a thousand times. ;-)

Edit:
Kalimdor (new) 40_46, 39_47, and 40_47 keep giving errors. so far they are the only ones your code is failing on, and they all happen to be adjacent to eachother

----------


## Flowerew

> Just tested the pre-release, flow, and it works great. Exported all of Azeroth so far. Of course I'll do it again once you finish, because of the WMO interiors not being there, but still, thanks so much.
> I wish I could rep you like a thousand times. ;-)
> 
> Edit:
> Kalimdor (new) 40_46, 39_47, and 40_47 keep giving errors. so far they are the only ones your code is failing on, and they all happen to be adjacent to eachother


Ok thanks for the feedback. I will check what's happening inside of them. Error reports are much appreciated. Keep 'em comming. I will also investigate the issues TOM_RUS had and probably also move to StormLib, if libmpq can't provide the most up-to-date data.

----------


## TOM_RUS

> Here's another screen of Orgrimmar: http://img340.imageshack.us/img340/7297/wowmapper02.png
> 
> Regarding your problem: It seems very strange, and I may have to get VS2010 to check it myself. Do you run 32 or 64 bit Windows? Have you had any hints as to when the crash occurs and why only 1 ADT seems to be displayed instead of a whole area? Any information would be greatly appreciated. Thanks for testing, TOM_RUS.


I've tried with orgrimmar, same problem. I've got same amount of triangles at the end (975727) as on your screenshot, but display is completely different: http://img11.imageshack.us/img11/1705/orgrimmarp.jpg

----------


## Cheatz0

Hey, first of all, good job sPeC! and Flowerew..it's really nice of you to share your work :Smile:  I have a question, which may or may not be totally unrelated to all of this: I heard Cataclysm will bring about a new type of phasing system, for the terrain.. have you guys found a way to read these different phases? Im not sure where to look myself, as I'm still trying to figure out the mpq formats and whatnot. Not even sure this would be a problem, I might just be thinking too far ahead  :Smile:

----------


## ostapus

was playing with svn version of wowmapper (well, tried to play), and it failed @ kalimdor 34 44 in parsing parseMh2oChunk. there is something wrong w/ chunk #38, layer 1, weird values.

----------


## Flowerew

> was playing with svn version of wowmapper (well, tried to play), and it failed @ kalimdor 34 44 in parsing parseMh2oChunk. there is something wrong w/ chunk #38, layer 1, weird values.


Commited a new version. MH2O bug should be gone now, the code is still in there but it's not used, because it's causing to much trouble right now, and I've to focus on other parts first. WMO interior has also been added to the code and terrain/doodad/wmo geometry should now be 100% present for all areas (if not, just report it). Sorry TOM_RUS, but I did not fix your problem yet, but it's definitely on my todo list. Cheers

----------


## QKdefus

im probably doing something wrong. the mesh exporter seems to crash on "Processing: (1) World\maps\Azeroth\Azeroth_35_20.adt 306 kb" / "libmpq__file_unpacked_size failed (-10)"
and just out of curiosity i tried to build your svn project, but it says it cannot open or include glm.hpp and sdl.h ? : )

----------


## ostapus

release version won't work with wow after 4.0 patch, use svn one. update the include/library path in projects

---------- Post added at 08:10 PM ---------- Previous post was at 08:09 PM ----------

btw: dunno about cv9, but vc10 produce the error on 

uid_map.insert( UidMap_t::value_type( wmo.info.uid, 0 ) );
fix
uid_map.insert( UidMap_t::value_type( wmo.info.uid, *(void*)* 0 ) );

----------


## TOM_RUS

> release version won't work with wow after 4.0 patch, use svn one. update the include/library path in projects
> 
> ---------- Post added at 08:10 PM ---------- Previous post was at 08:09 PM ----------
> 
> btw: dunno about cv9, but vc10 produce the error on 
> 
> uid_map.insert( UidMap_t::value_type( wmo.info.uid, 0 ) );
> fix
> uid_map.insert( UidMap_t::value_type( wmo.info.uid, *(void*)* 0 ) );


Yeah, that fix was posted on previous page.

Do you have same display issues like showed on my screenshots when compiling with VS2010?:
http://www.mmowned.com/forums/world-...ml#post1991525
http://www.mmowned.com/forums/world-...ml#post1992323

----------


## ostapus

oh, missed that... anyway that is easy one to fix byself  :Smile:  i had no issue with latest svn (just 1 adt shows ?) , whole oggrimar was shown.
win 7 x64 here.

----------


## _Mike

> Yeah, that fix was posted on previous page.
> 
> Do you have same display issues like showed on my screenshots when compiling with VS2010?:
> http://www.mmowned.com/forums/world-...ml#post1991525
> http://www.mmowned.com/forums/world-...ml#post1992323


It displays okey for me, win7 x64, vs2010, compiled as 32bit. Geforce 280
Here's a screenshot of area 14, durotar. http://dl.dropbox.com/u/12654979/area_14.png

I tried running it quickly on a friends computer which has an integrated intel gpu and it looked really weird. I couldn't get a screenshot though. I think it might be a problem with the renderer itself and not the parser.

Edit: using revision 46

----------


## ostapus

btw, demo project iterates over all adts to find out the ones belong to area id, is this info available somewhere ? no complain about it just kinda slow  :Smile:

----------


## TOM_RUS

> I think it might be a problem with the renderer itself and not the parser.


Yeah, most likely just visual hardware dependent bug then...
Can someone compile it in VS2010 with game path "G:\\Games\\World of Warcraft\\Data" just to check if it's really hardware dependent or some other bug? Because I tried to send my binaries to other ppl and they had exactly same issues as me. May be something wrong with my compiler...

----------


## ostapus

small note in 

adt_ss << zone_path << "_" << iter->x << "_" << iter->y;

adt are name_Y_X, so should be 

adt_ss << zone_path << "_" << iter->y << "_" << iter->x;

just to avoid confusions

----------


## adaephon

TOM_RUS: http://dl.dropbox.com/u/2660220/Binaries.zip Compiled with VS 2010 one loads Orgrimmar, another loads Elywnn Forest

Flowerew: Awesome work! +rep

Edit: Updated binaries with a version (Generic) that allows you to enter Data Path, Zone Path and Zone Id at the command line i.e. 

```
Sample_D3dByAreaId.exe "G:\Games\World of Warcraft\Data" "world\maps\azeroth\azeroth" 12
```

If an argument isn't included it uses defaults, but it doesn't do any smart parsing. First argument is always data, followed by zone, followed by id. So if you want to change the default id, you have to specify data and zone path arguments.

----------


## TOM_RUS

> TOM_RUS: http://dl.dropbox.com/u/2660220/Binaries.zip Compiled with VS 2010 one loads Orgrimmar, another loads Elywnn Forest


Thanks. Checked generic version, same issues as I posted above. Now we can be sure that it's not problem with compiler, but some hardware dependent problem...

----------


## Flowerew

> Thanks. Checked generic version, same issues as I posted above. Now we can be sure that it's not problem with compiler, but some hardware dependent problem...


I don't know if that's a fix. But could you try to create the IDirect3D9Device in _Renderer::initDirect3D()_ function with *D3DCREATE_SOFTWARE_VERTEXPROCESSING* insead of *D3DCREATE_HARDWARE_VERTEXPROCESSING*. Just a guess right now.

Edit: There will be a check against Direct3D device caps in the next version of the sample to make sure the device is created with the correct flags and draw calls use the right amount of vertices per batch.

----------


## TOM_RUS

> I don't know if that's a fix. But could you try to create the IDirect3D9Device in _Renderer::initDirect3D()_ function with *D3DCREATE_SOFTWARE_VERTEXPROCESSING* insead of *D3DCREATE_HARDWARE_VERTEXPROCESSING*.


Doesn't work, same problem, the only difference I noticed is that renderer a lot more slow with software flag.

----------


## Flowerew

> Doesn't work, same problem, the only difference I noticed is that renderer a lot more slow with software flag.


Can you do me favor and take a screenshot of your device caps like this one: http://img405.imageshack.us/img405/9918/devcaps.png. The tool can be found in your DirectX SDK start menu entry. I hope it sheds some light on your issue.  :Frown:

----------


## _Mike

> Can you do me favor and take a screenshot of your device caps like this one: http://img405.imageshack.us/img405/9918/devcaps.png. The tool can be found in your DirectX SDK start menu entry. I hope it sheds some light on your issue.


You should check the HAL device caps though. The reference device is a pure software renderer.
(Or try running the demo project with the ref driver)

----------


## TOM_RUS

> Can you do me favor and take a screenshot of your device caps like this one: http://img405.imageshack.us/img405/9918/devcaps.png. The tool can be found in your DirectX SDK start menu entry. I hope it sheds some light on your issue.


http://img715.imageshack.us/img715/1970/caps1p.jpg

----------


## QKdefus

finally managed to build the svn rev46, should i just remove this from loading ? i figure its not used anymore.. or am i doing something wrong again ? ^^


```
Load "wow-update-oldworld-13286.MPQ"Cannot open K:\WowI\Data\wow-update-oldworld-13286.MPQ libmpq__file_unpacked_size failed
```

edit:
after removing those lines and figuring out how to move around in wowmapper :P
orgrimmar http://img819.imageshack.us/img819/6472/31834797.jpg

nice work Flowerew : )

----------


## Flowerew

> You should check the HAL device caps though. The reference device is a pure software renderer.
> (Or try running the demo project with the ref driver)


Yeah my bad, I was in a little hurry and just did quick screen right before work was over. The HAL device is ofc the right one, but nonetheless, the updated sample will take actual hardware and its devcaps into account. Cheers




> finally managed to build the svn rev46, should i just remove this from loading ? i figure its not used anymore.. or am i doing something wrong again ? ^^
> 
> 
> ```
> Load "wow-update-oldworld-13286.MPQ"Cannot open K:\WowI\Data\wow-update-oldworld-13286.MPQ libmpq__file_unpacked_size failed
> ```
> 
> edit:
> after removing those lines and figuring out how to move around in wowmapper :P
> ...


Haha, nice screen. Nice chat!  :Wink:  you should use a release build though if you just want to parse data.  :Stick Out Tongue:

----------


## dook123

I was on my mobile when he spammed that crap :P. I think I am missing the connection of how this fits into everything. It goes through the wow map files to prepare them for navmesh? Its early morning for me  :Smile:  go easy on me! Great work so far flowerew.

----------


## Flowerew

> I was on my mobile when he spammed that crap :P. I think I am missing the connection of how this fits into everything. It goes through the wow map files to prepare them for navmesh? Its early morning for me  go easy on me! Great work so far flowerew.


It can be used for several things, but the main reason for people here is probably the extraction of WoW's geometry so it can be further processed by recast to generate a navmesh, which actually gives your bot a perception of the world surrounding it. Navigation is probably the most important part of a bot, which most if not all people who are writing bots will agree on. So it's a big part of the whole picture.

----------


## dook123

Does this create the obj files for the current version you uploaded?

----------


## Flowerew

> Does this create the obj files for the current version you uploaded?


If you're talking about the current sample project that's included, and wether it produces obj files which can be read by recast demo app, the answer is: no.

----------


## dook123

Your assumption was correct. Well, even without that piece, great work!  :Smile:  This is a portion of gaming I am completely unfamiliar with (rendering/maps/navmesh). It is very intriguing though. Keep up the good work.

----------


## QKdefus

> Haha, nice screen. Nice chat!  you should use a release build though if you just want to parse data.


thank you! well, thanks to you : P

was the first build so i think i forgot, went on to use release build after i came across a post mention the speed of the parser. quite an improvment vs debug build : )
anyways after looking around in the wowmapper world i noticed several "spikes" sort of, took a closer look and noticed its three's ? 
but when i compared wow world to wowmapper it looks like a lot of three's are left out ? is that normal ? 
one other thing if u look at the crane in top right corner i noticed its just a big block is this due to its an animated object? i noticed this at the front gate's of orgrimmar as well
probably not important, just thought id mention it : )

----------


## Flowerew

> thank you! well, thanks to you : P
> 
> was the first build so i think i forgot, went on to use release build after i came across a post mention the speed of the parser. quite an improvment vs debug build : )
> anyways after looking around in the wowmapper world i noticed several "spikes" sort of, took a closer look and noticed its three's ? 
> but when i compared wow world to wowmapper it looks like a lot of three's are left out ? is that normal ? 
> one other thing if u look at the crane in top right corner i noticed its just a big block is this due to its an animated object? i noticed this at the front gate's of orgrimmar as well
> probably not important, just thought id mention it : )


I'm at work so I can't check, but it seems like some doodads are skipped or left out. I will put this on my todo list, thanks.

----------


## QKdefus

> I haven't had no problems so far. Listfiles seem to be ok, and even expansion3.mpq has been read without problems. Same goes for wow-update-xxxxx.mpq, so I dont know what you mean, TOM_RUS.


loadMpq( mpq_h, "wow-update-oldworld-13286.MPQ" );
loadMpq( mpq_h, "expansion3.MPQ" );

weird, i cant load those mpq's in a build.. cmd error result below

Load "expansion3.MPQ"Cannot open K:\WowI\Data\expansion3.MPQ libmpq__archive_open failed
Load "wow-update-oldworld-13286.MPQ"Cannot open K:\WowI\Data\wow-update-oldworld-13286.MPQ libmpq__file_unpacked_size failed

edit: after looking in wow folder it turns out i dont even have a file named expansion3.mpq ^^ my bad

edit2: wow-update-oldworld-13286.MPQ seemd to be corrupt for some reason , got it from a friend of mine and it loaded fine

----------


## _Mike

> loadMpq( mpq_h, "wow-update-oldworld-13286.MPQ" );
> loadMpq( mpq_h, "expansion3.MPQ" );


It's 13287
expansion3.mpq is if you have cataclysm.

----------


## QKdefus

> It's 13287
> expansion3.mpq is if you have cataclysm.


wow-update-_oldworld_ says 13286 : ) its listed in wowmapper source and my game folder.. tho i tried to load it with mpqeditor it says the file is corrupt for some reason. 

theres the file wow-update-13287 that one reads just fine, was talking about oldworld one : )

----------


## _Mike

> wow-update-_oldworld_ says 13286 : ) its listed in wowmapper source and my game folder.. tho i tried to load it with mpqeditor it says the file is corrupt for some reason. 
> 
> theres the file wow-update-13287 that one reads just fine, was talking about oldworld one : )


Oh yeah sorry, I missed the oldworld part. Probably corrupt file then because I get no load errors from it. Try running the repair util.

----------


## RivaLfr

I try to export the Area or tile to .obj (for recast) and this don't work fine.

Sample of result for PvpZone01_31_32: (img) UpImg Image Hosting-test.png (.obj) MEGAUPLOAD - The leading online storage and file delivery service

I use this code:


```
  // Save to .obj
  std::cout << "Make file: " << areaId << ".obj";
            // Write the vertex's  
  std::stringstream ss;
          for (int i = 0; i < vertices.size(); i++)
	  {
		  ss << "v " << (vertices[i].x) << ' ' << (vertices[i].y) << ' ' << (vertices[i].z) << '\n';
	  }
		  ss << '\n';
	  for (int i = 0; i < indices.size();)
	  {
		  ss << "f " << (indices[i++]+1) << ' ' << (indices[i++]+1) << ' ' << (indices[i++]+1) << '\n';
	  }
	  std::stringstream sFileName;
      sFileName << areaId << ".obj";
      std::fstream fs(sFileName.str().c_str(), std::fstream::out|std::fstream::binary);
	  fs << ss.str();
	  fs.close();
	  std::cout << "File saved.";
```

 (before the code "// render loop")


Someone already had this problem? Because I not see an error in my code.

I try with others tile and zone, the m2 objet dump work fine but the matrix is beug.


Edit: Elwynn Forrest > http://upimg.org/show.php/2632_testRecast.png.html

----------


## Flowerew

> I try to export the Area or tile to .obj (for recast) and this don't work fine.
> 
> Sample of result for PvpZone01_31_32: (img) UpImg Image Hosting-test.png (.obj) MEGAUPLOAD - The leading online storage and file delivery service
> 
> I use this code:
> 
> 
> ```
>   // Save to .obj
> ...


Why do you use a stringstream? Just create a fstream and write directly to it like you do with your stringstream now. Also you open the file you write to in binary mode, whereas obj-files read by recast are simple ascii-files.

----------


## RivaLfr

Because I have try to make a navmesh file before, but for try .obj file is Better.

I have edit my code, but this not fix the problem.

EDIT:


```
	// Save to .obj
	std::cout << "Make file: " << areaId << ".obj" << std::endl;
	std::ofstream fs("Dump.obj", std::ios::out | std::ios::trunc);
	for (int i = 0; i < vertices.size(); i++)
	{
		fs << "v " << (vertices[i].x) << ' ' << (vertices[i].y) << ' ' << (vertices[i].z) << '\n';
	}
		fs << '\n';
	for (int i = 0; i < indices.size();)
	{
		fs << "f " << (indices[i++]+1) << ' ' << (indices[i++]+1) << ' ' << (indices[i++]+1) << '\n';
	}

	fs.close();
	std::cout << "File saved." << std::endl;
```

This is the new code but the result is same.

----------


## _Mike

> Because I have try to make a navmesh file before, but for try .obj file is Better.
> 
> I have edit my code, but this not fix the problem.
> 
> EDIT:
> 
> 
> ```
> 	// Save to .obj
> ...


Sequence point - Wikipedia, the free encyclopedia

----------


## dook123

Image
Sort of works, it looks kind of cool even though its wrong... Im not sure what 2 objects are but I dont play alliance much and visit these zones even less. The tree-like? thing to the left and the object past the mountains to the right.

----------


## hamburger12

This works verry well for me:


```
  std::fstream fs1("test.obj", std::fstream::out|std::fstream::binary);

  for (int i = 0; i < vertices.size(); i++)
  {
	  fs1 << "v " << (vertices[i].x) << ' ' << vertices[i].y << ' ' << (vertices[i].z) << '\n';
  }

  // Create faces based on the indices
  for (int i = 0; i < indices.size();)
  {
	 fs1 << "f " << indices[i++]+1;
	 fs1 << ' ' << indices[i++]+1;
	 fs1 << ' ' << indices[i++]+1 << '\n';
  }
```

----------


## dook123

@Hamburger12

Any images of your recast display?

----------


## _Mike

Area 12
http://dl.dropbox.com/u/12654979/recastdemo_area_12.jpg

I need to find a decent LoD algorithm though. The meshes are huge and I don't really need that much precision.

----------


## The-Guardian

I'm getting this error, the only thing I've gotten it to compile is Elwynn forest.

Ive tried using the wdt file and cmp file, nothing works.

----------


## QKdefus

. .

----------


## Gorzul

> Area 12
> http://dl.dropbox.com/u/12654979/recastdemo_area_12.jpg
> 
> I need to find a decent LoD algorithm though. The meshes are huge and I don't really need that much precision.


Have a look at MeshLab. You can use "Merge Close Vertices" and "Quadric Edge Collape Decimation" to reduce the number of faces.

----------


## dook123

Anyone know why the door is shut on orgrimmar?

Album pic 1

----------


## namreeb

Random guess:

If memory serves, there are some vertices which are not marked for collision. For purposes of generating a navigation mesh, these vertices should be discarded. Perhaps they're not, or the format for them has changed with the new expansion?

----------


## MaiN

> Random guess:
> 
> If memory serves, there are some vertices which are not marked for collision. For purposes of generating a navigation mesh, these vertices should be discarded. Perhaps they're not, or the format for them has changed with the new expansion?


Nope, they're still the same. They're located in the MOPY chunk of the WMO groups.

----------


## caytchen

[IMGL]http://imgur.com/wEN8W.png[/IMGL]

If you properly read it, theres nothing blocking the entrance.

----------


## dook123

Im trying to understand the structure of the WoW MPQ. Is the entrance a doodad? Im thinking no. Yours is much cleaner than mine. Any tips for the entrance to orgrimmar issues?

----------


## namreeb

Did you check my suggestion?

WMO - WoW.Dev Wiki

----------


## RivaLfr

http://imgup.co.nz/i/anonymous/12919...yPvpZone01.png
Sample code to export to .obj file tile by tile (and others config (export tile, export all, ...)):

_Sample_D3dByAreaId.cpp_

```
/** NO PUBLIC EXAMPLE! Just for testing purposes!!! You have been warned! **/

#include "../src/mpqhandler.h"
#include "../src/wdt.h"
#include "../src/adt.h"
#include "../src/obj0.h"
#include "../src/m2.h"
#include "../src/wmomodel.h"
#include "renderer.h"
#include <string>
#include "windows.h"

//- Functions ------------------------------------------------------------------
/** Just a list of MPQs we want to load. **/
void loadAllMpqs( MpqHandler &mpq_h );
/** Load MPQ by filename. **/
void loadMpq( MpqHandler &mpq_h, const std::string &filename );
/** Load *.adt and *.obj0 files from MPQ. **/
bool loadAdt( MpqHandler &mpq_h, const std::string &name,
              BufferS_t *adt_buf, BufferS_t *obj_buf );
/** Load WMOs and doodads here. **/
void loadObjectReferences( MpqHandler &mpq_h, Obj0 &obj0, Indices32_t *indices,
                           Vertices_t *vertices, Normals_t *normals );
/** Filter terrain by area ID and add them to our coordinate vector. **/
void getCoordsByAreaId( MpqHandler &mpq_h, const AdtCoords_t &original_coords,
                        const std::string &zone_path, uint32_t area_id,
                        AdtCoords_t *coords, uint32_t x = -1, uint32_t y = -1, bool dumpAll = false);
/** Used to retrieve doodad geometry. **/
bool getDoodadGeometry( MpqHandler &mpq_h, const std::string &doodad_name,
                        Indices32_t *doodad_indices, Vertices_t *doodad_vertices,
                        Normals_t *doodad_normals );

//- WoW related ----------------------------------------------------------------
UidMap_t uid_map;
BufferS_t adt_buf, obj_buf;

//------------------------------------------------------------------------------
int main( int arch, char **argv ) {
	// Load MPQ file
	MpqHandler mpq_h( "E:\\jeux\\World of Warcraft\\Data" );
	loadAllMpqs( mpq_h );

	// load WDT file which tells us what ADT tiles to load
	BufferS_t file_buffer;
	std::string zone_path( "world\\maps\\PvpZone01\\PvpZone01" );
	mpq_h.getFile( zone_path + ".wdt", &file_buffer );

	// Others Option
	uint32_t areaId = -1;
	uint32_t xTile = -1;
	uint32_t yTile = -1;
	bool dumpAll = true;
	bool showMap = false;
	bool saveTile = true; // Save to .obj file

	// create geometry buffer
	Vertices_t vertices;
	Indices32_t indices;
	Normals_t normals;
	CreateDirectoryA("dump", NULL);

	// parse WDT files
	Wdt wdt( file_buffer );

	// GET COORDS BY AREA ID! AREA ID -> 12 (Elwynn Forrest), 14 (Durotar)
	AdtCoords_t coords;
	getCoordsByAreaId( mpq_h, wdt.getAdtCoords(), zone_path, areaId, &coords, xTile, yTile, dumpAll );

	if ( coords.size() <= 0 ) {
	std::cout << "Zone not found." << std::endl;
	return 0;
	}

	// load found areas and get geometry
	for ( AdtCoords_t::const_iterator iter = coords.begin();
		iter != coords.end();
		++iter ) {
	// clear buffers
	adt_buf.clear();
	obj_buf.clear();
	// create file string
	std::stringstream adt_ss;
	adt_ss << zone_path << "_" << iter->x << "_" << iter->y;

	// load adt and obj files from mpq
	loadAdt( mpq_h, adt_ss.str(), &adt_buf, &obj_buf );
	Adt adt( adt_buf );

	// get terrain geometry
	if (saveTile)
	{
		vertices.clear();
		indices.clear();
		normals.clear();
	}
	const AdtTerrain_t &adt_terr = adt.getTerrain();
	for ( AdtTerrain_t::const_iterator terr = adt_terr.begin();
		  terr != adt_terr.end();
		  ++terr ) {
	  mergeIndices( terr->indices, vertices.size(), &indices );
	  mergeVertices( terr->vertices, &vertices );
	  mergeNormals( terr->normals, &normals );
	}

	// parse object references
	if ( obj_buf.size() ) {
	  Obj0 obj0( obj_buf );
	  loadObjectReferences( mpq_h, obj0, &indices, &vertices, &normals );
	}

	if (saveTile)
	{
	  // Save to .obj
	  std::stringstream fileName;
	  fileName.clear();
	  fileName << "dump\\" << iter->x << "_" << iter->y << ".obj";
	  std::cout << "Save to \"" << fileName.str() << "\" file." << std::endl;
	  
	  std::fstream fs1((const char*)(fileName.str().c_str()), std::fstream::out|std::fstream::binary);
	  for (int i = 0; i < vertices.size(); i++)
	  {
		  fs1 << "v " << (vertices[i].x) << ' ' << vertices[i].y << ' ' << (vertices[i].z) << '\n';
	  }
	  for (int i = 0; i < indices.size();)
	  {
		 fs1 << "f " << indices[i++]+1;
		 fs1 << ' ' << indices[i++]+1;
		 fs1 << ' ' << indices[i++]+1 << '\n';
	  }
	}
	}


	if (showMap && !saveTile)
	{
	  // initialize renderer
	  Renderer renderer( 800, 600, "WoWMapper" );
	  if ( !renderer.initialize() ) {
		return -1;
	  }

	  // look at geometry
	  renderer.getCamera().setPosition( vertices[0] );

	  // create direct3d buffers
	  size_t ib_size = sizeof( uint32_t ) * indices.size();
	  size_t vb_size = sizeof( CustomVertex_s ) * vertices.size();
	  DWORD format = D3DFVF_XYZ | D3DFVF_NORMAL;

	  // create d3d buffers and get device
	  IDirect3DIndexBuffer9 *ib = NULL;
	  IDirect3DVertexBuffer9 *vb = NULL;
	  renderer.createBuffers( ib_size, vb_size, format, &ib, &vb );
	  IDirect3DDevice9 *d3d_dev9 = renderer.getDevice();

	  // print num triangles
	  std::cout << "Num Triangles: " << indices.size()/3 << std::endl;

	  // copy vertex buffer
	  CustomVertex_s *vtx_buf;
	  vb->Lock( 0, 0, (void**)&vtx_buf, 0 );
	  for ( int i = 0; i < vertices.size(); i++ ) {
		vtx_buf[i].pos.x = vertices[i].x;
		vtx_buf[i].pos.y = vertices[i].y;
		vtx_buf[i].pos.z = vertices[i].z;
		vtx_buf[i].normal.x = normals[i].x;
		vtx_buf[i].normal.y = normals[i].y;
		vtx_buf[i].normal.z = normals[i].z;
	  }
	  vb->Unlock();

	  // copy index buffer
	  void *idx_buf;
	  ib->Lock( 0, 0, (void**)&idx_buf, 0 );
	  memcpy( idx_buf, &indices[0], indices.size() * sizeof( uint32_t ) );
	  ib->Unlock();

	  uint32_t num_batches = indices.size() / 0xffff;
	 
	  // render loop
	  while( 1 ) {    
		renderer.begin();
		renderer.initScene();

		// set buffers
		d3d_dev9->SetStreamSource( 0, vb, 0, sizeof( CustomVertex_s ) );
		d3d_dev9->SetFVF( format );
		d3d_dev9->SetIndices( ib );
	    
		// draw batches, i know some are missing but that's ok here
		for ( uint32_t n = 0; n < num_batches; n++ ) {
		  d3d_dev9->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 0xffff, n*0xffff, 0xffff/3 );
		}

		renderer.end();
	  }

	  mpq_h.clear();
	}
	else
	{
		std::cout << "Finish" << std::endl;
		std::cin ;
	}
  return 0;
}

//------------------------------------------------------------------------------
void loadAllMpqs( MpqHandler &mpq_h ) {

  loadMpq( mpq_h, "wow-update-13329.MPQ" );
  loadMpq( mpq_h, "wow-update-13287.MPQ" );
  loadMpq( mpq_h, "wow-update-13205.MPQ" );
  loadMpq( mpq_h, "wow-update-13164.MPQ" );
  loadMpq( mpq_h, "wow-update-oldworld-13286.MPQ" );
  loadMpq( mpq_h, "wow-update-oldworld-13154.MPQ" );
  loadMpq( mpq_h, "expansion3.MPQ" );
  loadMpq( mpq_h, "expansion2.MPQ" );
  loadMpq( mpq_h, "expansion1.MPQ" );
  loadMpq( mpq_h, "world.MPQ" );
  loadMpq( mpq_h, "OldWorld.MPQ" );
  loadMpq( mpq_h, "art.MPQ" );
}

//------------------------------------------------------------------------------
void loadMpq( MpqHandler &mpq_h, const std::string &filename ) {
  std::cout << "Load \"" << filename << "\"";
  std::cout << " (" << mpq_h.addFile( filename ) << ")" <<std::endl;
}

//------------------------------------------------------------------------------
bool loadAdt( MpqHandler &mpq_h, const std::string &name,
              BufferS_t *adt_buf, BufferS_t *obj_buf ) {
  std::string adt_str = name + std::string( ".adt" );
  std::string obj_str = name + std::string( "_obj0.adt" );
  
  return mpq_h.getFile( adt_str, adt_buf ) && mpq_h.getFile( obj_str, obj_buf );
}

//------------------------------------------------------------------------------
void loadObjectReferences( MpqHandler &mpq_h, Obj0 &obj0, Indices32_t *indices,
                           Vertices_t *vertices, Normals_t *normals ) {
  // get doodads/WMOs of ADT
  const ObjectReferences_t &obj_refs = obj0.getObjectRefs();
  for ( ObjectReferences_t::const_iterator ref = obj_refs.begin();
        ref != obj_refs.end();
        ++ref ) {
    // get unique doodads here, notice: you can speed things up if you buffer
    // already loaded objects here :)
    for ( int d = 0; d < ref->doodadIndices.size(); d++ ) {
      Doodad_s doodad;
      obj0.getDoodad( ref->doodadIndices[d], &doodad );

      // find unique identifier in map, only one uid can be present
      UidMap_t::iterator found = uid_map.find( doodad.info.uid );

      // unique identifier not found: insert UID in map
      if ( found == uid_map.end() ) {
        uid_map.insert( UidMap_t::value_type( doodad.info.uid, 0 ) );

        BufferS_t doodad_buf;
        mpq_h.getFile( doodad.name, &doodad_buf );

        // doodad buffers
        Indices32_t m2_i;
        Vertices_t m2_v;
        Normals_t m2_n;

        // if doodad geometry is present: transform and merge
        if ( getDoodadGeometry( mpq_h, doodad.name, &m2_i, &m2_v, &m2_n ) ) {
          // bring vertices to our coordinate system
          transformVertices( doodad.info.pos, doodad.info.rot,
                             doodad.info.scale / 1024, &m2_v ); 


          mergeIndices( m2_i, vertices->size(), indices );
          mergeVertices( m2_v, vertices );
          mergeNormals( m2_n, normals );
        }
      }
    }

    // get unique WMOs here, same thing as above: buffer -> +speed !
    for ( int d = 0; d < ref->wmoIndices.size(); d++ ) {
      uint32_t obj_index = ref->wmoIndices[d];
      // get wmo from object file
      Wmo_s wmo;
      obj0.getWmo( obj_index, &wmo );

      // find WMOs UID in our map
      UidMap_t::iterator found = uid_map.find( wmo.info.uid );

      // same procedure as above
      if ( found == uid_map.end() ) {
        uid_map.insert( UidMap_t::value_type( wmo.info.uid, 0 ) );

        BufferS_t wmo_buf;
        mpq_h.getFile( wmo.name, &wmo_buf );

        // parse wmo data
        WmoModel wmo_model( wmo_buf );
        wmo_model.loadGroups( wmo.name, mpq_h );

        // wmo buffers
        Indices32_t wmo_i;
        Vertices_t wmo_v;
        Normals_t wmo_n;

        wmo_model.getIndices( &wmo_i );
        wmo_model.getVertices( &wmo_v );
        wmo_model.getNormals( &wmo_n );

        // bring vertices to our coordinate system
        const ModfChunk_s::WmoInfo_s &info = obj0.wmoInfo()[obj_index];
        transformVertices( info.pos, info.rot, 1.0f, &wmo_v );

        mergeIndices( wmo_i, vertices->size(), indices );
        mergeVertices( wmo_v, vertices );
        mergeNormals( wmo_n, normals );

        // get interior doodads for WMOs
        const ModnChunk_s &modn_chunk = wmo_model.getModnChunk();
        const ModdChunk_s::DoodadInformations_t &modd_infos = wmo_model.getModdChunk().infos;        
        for ( ModdChunk_s::DoodadInformations_t::const_iterator iter = modd_infos.begin();
              iter != modd_infos.end();
              ++iter ) {
          // doodad name
          std::string doodad_name( (const char*)&modn_chunk.doodadNames[iter->id] );
          doodad_name.replace( doodad_name.size() - 4, 4, ".M2" );
          BufferS_t doodad_buf;
          mpq_h.getFile( doodad_name, &doodad_buf );

          // load doodad if buffer has data
          if ( doodad_buf.size() ) {
            M2 m2( doodad_buf );

            Indices32_t m2_i;
            Vertices_t m2_v;
            Normals_t m2_n;

            m2.getBoundingIndices( &m2_i );
            m2.getBoundingVertices( &m2_v );
            m2.getBoundingNormals( &m2_n );

            // interior doodads have to be transformed by their parent WMO's
            // transformation first
            for ( int i = 0; i < m2_v.size(); i++ ) {
              glm::vec3 &vtx = m2_v[i];
              vtx = glm::rotate( iter->rotation, vtx ) * iter->scale + iter->position;
            }

            // now transform by 
            transformVertices( info.pos, info.rot, 1.0f, &m2_v );

            mergeIndices( m2_i, vertices->size(), indices );
            mergeVertices( m2_v, vertices );
            mergeNormals( m2_n, normals );
          }
        }
      }
    }
  }
}

//------------------------------------------------------------------------------
void getCoordsByAreaId( MpqHandler &mpq_h, const AdtCoords_t &original_coords,
                        const std::string &zone_path, uint32_t area_id,
                        AdtCoords_t *coords, uint32_t x, uint32_t y, bool dumpAll ) {
  int count = 0;
  for ( AdtCoords_t::const_iterator iter = original_coords.begin();
        iter != original_coords.end();
        ++iter ) {
    count++;
    //if ( count < 256 || count > 512 ) continue;

    // create file string
    std::stringstream adt_ss;
    adt_ss << zone_path << "_" << iter->x << "_" << iter->y;
    std::cout << count << " " << adt_ss.str();
     
    adt_buf.clear();
    obj_buf.clear();
    // loading obj files here is pointless, but it's a reused function so live with it :p
    loadAdt( mpq_h, adt_ss.str(), &adt_buf, &obj_buf );

    Adt adt( adt_buf );
    const AdtTerrain_t &adt_terr = adt.getTerrain();
    for ( AdtTerrain_t::const_iterator terr = adt_terr.begin();
          terr != adt_terr.end();
          ++terr ) {
      if ( terr->areaId == area_id || dumpAll || x == iter->x && y == iter->y) {
        std::cout << " found area";
        coords->push_back( *iter );
        break;
      }
    }
    std::cout << std::endl;
  }
}

//------------------------------------------------------------------------------
bool getDoodadGeometry( MpqHandler &mpq_h, const std::string &doodad_name,
                        Indices32_t *doodad_indices, Vertices_t *doodad_vertices,
                        Normals_t *doodad_normals ) {
  BufferS_t doodad_buf;
  mpq_h.getFile( doodad_name, &doodad_buf );

  // load doodad if buffer has data
  if ( doodad_buf.size() ) {
    M2 m2( doodad_buf );

    // only get data if parameter is passed
    if ( doodad_indices ) {
      m2.getBoundingIndices( doodad_indices );
    }

    if ( doodad_vertices ) {
      m2.getBoundingVertices( doodad_vertices );
    }

    if ( doodad_normals ) {
      m2.getBoundingNormals( doodad_normals );
    }

    return true;
  }

  return false;
}
```

----------


## dook123

Thanks for the release Rivalfr. It has some nice components to it that I had not thought of and helped me understand this project a lot more. 

I still have the door error with orgrimmar. Ill post back here if I figure it out.

----------


## namreeb

...............

----------


## dook123

> ...............


:P I have not figured out how to exclude those verticies in the MOPY chunk... if I do I will post it.

----------


## namreeb

What do you mean you haven't figured out how to do it? You simply ignore the triangles with the appropriate flags.

See here:



```
			// process each triangle in the current group file
			for (int i = 0; i < groupFiles[g]->MaterialsChunk->TriangleCount; i++)
			{
				// flags != 0x04 implies collision.  materialId = 0xFF (-1) implies a non-rendered collideable triangle.
				if (groupFiles[g]->MaterialsChunk->Flags[i] & 0x04 && groupFiles[g]->MaterialsChunk->MaterialId[i] != 0xFF)
					continue;
```

----------


## dook123

You are correct, I was in the process of writing it now. But since Im am still learning the structure I planned to debug it to gain some knowledge. 

Thank you for your posts and patience.

---------- Post added at 01:15 PM ---------- Previous post was at 12:38 PM ----------

Read the wiki and your code and I thought I understood it. I saw the comments made in the wiki about these types as well. Ran the code and it excluded all the verticies that built Orgrimmar so I must have done it wrong. I am debugging it some more. Will do an edit to this post if I find the problem soon in case others have a similar issue.

---------- Post added at 02:06 PM ---------- Previous post was at 01:15 PM ----------

I was checking the wrong data for the ID. Continuing on.

----------


## dook123

Looks like WoWMapper has the code for WMOGroup but it is crashing on with no errors currently. I believe the MOPY chunk is held within the WMOGroup can anyone confirm this?

----------


## namreeb

This question was already answered for you.




> Nope, they're still the same. They're located in the MOPY chunk of the WMO groups.

----------


## dook123

Correct, thanks MaiN!

----------


## dook123

So most of what I said was gibberish or wrong. WoWMapper seems to have what I need to get at the right data. Something went wrong though.

 The door is open but a lot of other stuff is gone that shouldnt be

----------


## dook123

> What do you mean you haven't figured out how to do it? You simply ignore the triangles with the appropriate flags.
> 
> See here:
> 
> 
> 
> ```
> 			// process each triangle in the current group file
> 			for (int i = 0; i < groupFiles[g]->MaterialsChunk->TriangleCount; i++)
> ...



This solution was correct in its entirety to fix the problem with having extra verticies. It has to do with extra data stored in the MPQ that is used for collision while not being used for displaying purposes. The sample in wowmapper was not considering them but as far as I know its not even a full release of the project yet. 

++Rep to namreeb for both the correct suggestion and solution

Org Tile Front Gate Final

----------


## namreeb

Glad you figured it out, because I wasn't really understanding anything else you were saying.  :Smile:

----------


## dook123

Most of it was me trying to understand the C++ Ive been out of touch with it for awhile. I couldnt rep you for your suggestion and your code but thank you again! You got at least +1 rep  :Wink:  from me.

----------


## namreeb

No sweat. Reputation in this section means nothing.

----------


## amadmonk

*sigh*

So, I'm going to be forced to port this to C#/C++/CLI to use it in my WPF app, aren't I?

(Note: just the simple fix of enabling CLR on the project was insufficient... something about the app didn't play nice with C++/CLI).

Edit: hmm never mind. Fiddled with a few linker switches and got wowmapper compiled into a C++/CLI assembly. I'm going to move some methods around to make them more CLR-friendly, then it should be possible to use wowmapper from C#.

----------


## namreeb

If you can wait you can use namigator.

----------


## amadmonk

Alright, I'll get back to .. um.. hm. There's not much non-navigational code left on my bots...

----------


## raindog

> If you can wait you can use namigator.


When is said namigator released?

----------


## namreeb

At the moment I'm not planning on releasing it to the public, though I may post it to the elite mem edit section.

----------


## cvccbum

Namigator eh? this sounds interesting  :Smile:  I've been trying to get a navmesh pathing system for my private bot down, but just can't seem to get it going perfect  :Frown:

----------


## namreeb

I am of course willing to assist people with specific questions. Feel free to post any in this forum.

----------


## RivaLfr

Have a difference between the position in adt and the position ingame?

Edit: 
Position in .obj file: _v 4266.67 39.5574 -1600_
Position in game (same tile): _X=1369, Y=-4376, Z=26_
It is a error with the extration or there is a interval?

----------


## caytchen

It's a different coordinate system.
WoW -> R+D: -Y, Z, -X
R+D -> WoW: -Z, -X, Y

This is what you get for releasing this stuff. Sigh.

----------


## Flowerew

> It's a different coordinate system.
> WoW -> R+D: -Y, Z, -X
> R+D -> WoW: -Z, -X, Y
> 
> This is what you get for releasing this stuff. Sigh.


Rewarding, isn't it?

----------


## RivaLfr

Thank, +rep.

I go try this. Because for the moment I not arrive to sync TileRecast/TileWow.

Edit:
Work fine! Thank

----------


## j005u

It appears some of the latest additions to wowmapper have broken cross-platform compatability. Namely sprintf_s and strtok_s.

edit: oh yeah, and it took me 4 hours to figure this out, but for the love of god, build in 32bit mode. structs are read directly from corresponding files and if your data types are off... i feel like murdering someone right now.

----------


## ostapus

anyone can provide tips to deal with m2ho chunk ? i am having issues to mark up/exclude water covered terrain. I've tried two ways
1. exclude based on rendermap (names from wowmapper)
2. exclude based on mask2 bytes array
no one seems to work (excluding/marking terrain) for 100% for me, i feel like i am missing something.

nvm.. figure it out.. renderMap works just fine.

----------


## ostapus

Decide to post question to this thread.
Question for those who are using recast for navigation - how do you build tiles ?
1. per adt basis ? in this case - adt size is 533.333 - you can't create mesh which will exactly fit this dimensions (recast is using int as cell size), therefore tiles on adt borders will overlap. Will it cause issues with detour ?

thanks

----------


## caytchen

> 1. per adt basis ? in this case - adt size is 533.333 - you can't create mesh which will exactly fit this dimensions (recast is using int as cell size), therefore tiles on adt borders will overlap. Will it cause issues with detour ?


Huh? Tile size is in voxels. To go from voxels to world units, you multiply the voxels with your cell size. So lets assume you want a tile size of 2000 voxels (more voxels means better precision and increased calculation time). You need to find the cell size in the equation 2000 * cs = 533 1/3, which is cs = 0.26666.. you get the idea. I agree there are some numerical stability problems here, mostly due to Blizzards odd choice of tile size, but it works just fine in practice.

----------


## ostapus

Thanks,
assume i want detour tile covers whole adt (as in you example), assume i build 2 tiles from 2 connected adts, when i add detours tiles into the mesh, are they going to be connected ? The reason - i can't load whole continent geometry due to size but rather have to load adt, recast it, dump to file, load another adt etc...
when i load 2 "separately" built tiles and add them to mesh - will detour have problem to connect adjusted polys ?

thanks

----------


## caytchen

Detour will automatically connect tiles - but only if you pass to Recast geometry for the border, i.e. you will have to load the surrounding ADTs of the one ADT whose tile you want to create. You have to specify a border area in the config or regions will be cut off one agent radius short of the tile bounds.

----------


## ostapus

So basically - geometry for the tile + border size (in voxels) required for proper tile generation. go it. thanks for information!
i've converted wowmapper to c# code, if anyone interested i can post it here.
for those who cares there is small bug in wowmapper, to be exact in obj0.cpp, here

// I believe there is no MCRW without MCRD chunks, but MCRD is always first
if ( mcnk_chunk.size ) {

... MCRW/MCRD processing
the bug is that MCRW can exists w/o MCRD therefore needs to check what chunk is here. By fixing this - it will fix some geometry errors i observed sometime.

----------


## namreeb

I can confirm what caytchen has said. You do need to provide some geometry to Recast beyond the border of your tile. This is basically because the algorithms Mikko uses are generic and cannot make assumptions (or permit you to make assertions) about what is beyond the tile. In this case the concern is what if there is a wall right off of the edge of the tile? This would mean that not only could you walk off the tile in this position, but you couldn't reach the edge of the tile either because your agent has width. That is the purpose of the max wall distance param Recast takes.

----------


## ostapus

I wonder what parameters others find to be most suitable to feed into recast/detour ? Anyone care to share please ?

thanks

----------


## namreeb

Which settings are you wondering about? Many of them depend on how big you want to make your tiles.

----------


## ostapus

agent radius/height, walkable angle, max climb. currently (for test purposes), i am using cs = 0.26 (adt size / 2000), 125 cs per tile, 16 tiles per adt.
is this CS size sufficiently small or too big ?
i am not really sure how big tiles i want, i am open for any suggestions/expirience

thanks

----------


## namreeb

Below are the settings I used when I was using Recast. Note that, though its not specifically documented, many of these settings are dependent on the others. That is why I made up a few variables of my own and set the Recast parameters in terms of them. This way I don't have to remember the relationships. For example, the cell size must perfectly divide the tile size. Another example is you must provide at least enough geometry beyond the tile boundary to account for half of an agent width (I think).

For accuracy, you want to pick a cell size that will nicely divide your agent's radius and a height that will nicely divide your agent's height and maximum step size. By nicely I don't necessarily mean divide exactly, but close to it. The closer you are, the more accurate you will be. However, to exactly divide everything perfectly, you'll have a cell size so small that your meshes will be enormous.

As for tile size, the problem I had with Recast was that with large tiles you can get long and skinny mesh polygons. This can give you some non-optimal paths because of the string pulling algorithm being used in Detour at the time. This may or may not still be the case, but currently I am experimenting with MCNK sized tiles.

I think MaiN does either four or 16 tiles per ADT.



```
        private const float TileSize = (533f + (1f / 3f));
        private const int TileVoxelSize = 1800;
        private const int MinRegionSize = 20;
        private const int MergeRegionSize = 40;

        private const float CellSize = TileSize / TileVoxelSize;
        private const float CellHeight = 0.4f;
        private const float WalkableSlopeAngle = 50f;
        private const float MaxSimplificationError = 1.3f;
        private const float DetailSampleDist = 3f;
        private const float DetailSampleMaxError = 1.25f;

        /// <summary>
        /// Height of wow toon
        /// </summary>
        private const float WorldUnitWalkableHeight = 1.652778f;

        /// <summary>
        /// Maximum height where slope is not considered
        /// </summary>
        private const float WorldUnitWalkableClimb = 1.0f;

        /// <summary>
        /// Radius of wow toon
        /// </summary>
        private const float WorldUnitWalkableRadius = 0.2951389f;

        private static readonly int WalkableHeight = (int)Math.Round(WorldUnitWalkableHeight / CellHeight);
        private static readonly int WalkableClimb  = (int)Math.Round(WorldUnitWalkableClimb  / CellHeight);
        private static readonly int WalkableRadius = (int)Math.Round(WorldUnitWalkableRadius / CellSize);
        private static readonly int MaxEdgeLen = WalkableRadius * 8;
        private static readonly int BorderSize = WalkableRadius + 4;
        private static readonly int TileWidth = TileVoxelSize + (BorderSize * 2);
```

----------


## ostapus

also, another probably noob question - object coordinates (say player), are they bottom (ground level) center of the model, center of the model and therefore "ground" points needs to be adjusted by height/t ( i am using height as 2 wu - is this ok ?)

another tia

----------


## namreeb

I'm not sure, but I don't understand why that matters?

----------


## caytchen

> As for tile size, the problem I had with Recast was that with large tiles you can get long and skinny mesh polygons. This can give you some non-optimal paths because of the string pulling algorithm being used in Detour at the time. This may or may not still be the case, but currently I am experimenting with MCNK sized tiles.


This happens if you use monotone partitioning, which is fine for small tile sizes but its practically useless for large tiles. See this blog post Digesting Duck: Monotone Regions
To "fix" that, watershed partitioning can be used, which is the default now anyway, I think.

(I noticed you've been looking to build your own Recast. Could you elaborate on the simplifications and improvements that can be made when specializing on WoW? I remember pendras thread, but I never understood why his system would perform magnitudes faster than Recast)

----------


## ostapus

Anyone can check for me kalimdor_37_23 map. On following pictures the players coordinates are "Mount Hyjal,4581.5273,-2959.8936,1066.5474" and that location happening to be under the stair. and that stair is actually doesn't look good to me (the next one further is looking ok though). My nav implementation stucks everytime over there. Is this something wrong with my model importing (the other models are looking ok) or ...

pictures:
http://ostap.us/5/p1.jpg
http://ostap.us/5/p2.jpg
http://ostap.us/5/p3.jpg

the coordinates from above reported from the in-game player's position in "stuck" place.

----------


## namreeb

> This happens if you use monotone partitioning, which is fine for small tile sizes but its practically useless for large tiles. See this blog post Digesting Duck: Monotone Regions
> To "fix" that, watershed partitioning can be used, which is the default now anyway, I think.
> 
> (I noticed you've been looking to build your own Recast. Could you elaborate on the simplifications and improvements that can be made when specializing on WoW? I remember pendras thread, but I never understood why his system would perform magnitudes faster than Recast)


It happens with watershed partitioning just the same. In fact my experience has been it is less prevalent when doing monotone partitioning. But Mikko's implementations are geared towards a dungeon style universe with long, narrow corridors.

As for what the motivation is for doing your own, there are three major elements.

1. I felt I would need to understand every element of this process if I wanted to extend the process to do 3d navigation properly.
2. As stated before, some of the algorithms used by R+D while they work in WoW are not ideal.
3. In response to one of your questions, yes it does go faster.

As for why pendra's implementation went so fast, I believe it is a combination of his access to a server designed for computational geometry related number crunching, the fact that his code was highly parellel, and being WoW specific does allow you to skip some serious number crunching. Most notable, you do not have to rasterize the entire terrain. In fact, you need only rasterize doodads and WMOs. When I wrote my height field generation class, I wrote it so I could easily switch between height map interpolation and rasterization for the terrain and liquid data, so I could see what the speed up is. It was a few months ago, but I'm pretty sure that by skipping the un-needed rasterization I saw the height field generation take about 60% of the time it had taken prior.

Also, Mikko rebuilds and iterates over his data structures a few times more than are necessary for the purposes of maintaining a compact form in your data structure. The idea is Mikko wants you to be able to read (from a file, socket, whatever) an entire mesh in one read operation. Reorganizing things into this form takes time. Look at the differences between the height field and what Mikko calls the compact height field.

Lastly, Mikko's code has a lot of bells and whistles that are simply not applicable. And it makes keeping current with his library a real pain in the butt. Especially when you are making changes to it to add things that are WoW specific. I had to keep a txt file in the SVN repo (and in the project itself for convenience sake) that itemized the changes to make once a new R+D revision had been inserted into our project.

Edit: I think I came off a bit too critical of Mikko's code. That is not my intention. I would not be anywhere without R+D as a reference. I think the drawbacks are relatively minor and completely necessary when writing something like this in a generic way as he has done.





> Anyone can check for me kalimdor_37_23 map. On following pictures the players coordinates are "Mount Hyjal,4581.5273,-2959.8936,1066.5474" and that location happening to be under the stair. and that stair is actually doesn't look good to me (the next one further is looking ok though). My nav implementation stucks everytime over there. Is this something wrong with my model importing (the other models are looking ok) or ...
> 
> pictures:
> http://ostap.us/5/p1.jpg
> http://ostap.us/5/p2.jpg
> http://ostap.us/5/p3.jpg
> 
> the coordinates from above reported from the in-game player's position in "stuck" place.


I don't quite understand. Are you saying that you cannot get the RecastDemo app to select the top of the stairs as the player position, only the terrain underneath it?

----------


## ostapus

Namreeb,

i am trying to say (sorry for my english), that the lower slope of that porch is missing, however in game - there is nice slope, the in game coordinates reported by staying on that slope somehow points inside the model (as you can see on pictures). so i was asking if someone can check their generated maps/geometry mesh for this specific place.

thanks

----------


## MaiN

> Anyone can check for me kalimdor_37_23 map. On following pictures the players coordinates are "Mount Hyjal,4581.5273,-2959.8936,1066.5474" and that location happening to be under the stair. and that stair is actually doesn't look good to me (the next one further is looking ok though). My nav implementation stucks everytime over there. Is this something wrong with my model importing (the other models are looking ok) or ...
> 
> pictures:
> http://ostap.us/5/p1.jpg
> http://ostap.us/5/p2.jpg
> http://ostap.us/5/p3.jpg
> 
> the coordinates from above reported from the in-game player's position in "stuck" place.


http://dl.dropbox.com/u/4368377/WoW/Kalimdor_37_23.jpg
Looks fine for me.

----------


## ostapus

Thanks MaiN,

going to dig wmo part.

----------


## amadmonk

Looks like Mikko is looking into 3D nav a lot lately too, namreeb. CF Digesting Duck: Loosely Ordered Mega Navigation Grids

Even if you're not actually based off of R+D these days, it might be educational to follow his thinking. I think that this idea of smaller "tiled" meshes fits a lot better with bot design, since the unwieldiness of giant "mega" meshes is one of the biggest problems I've faced trying to incorporate pathfinding into my bots, and since smaller tiles give a lot more opportunity for dynamically recalculating a mesh when navigability changes occur. Since I don't grind outside of instances, a lot of the optimizations that go into outdoors pathfinding are less than useless for me -- they obfuscate the data without benefiting me much. So, I'm curious to see where Mikko takes this new line of thought...

----------


## dook123

Hopefully someone can answer this but what is the best solution to solve the size issue with the exported wow maps in R+D?

Ive used WoWMapper to export a full map, say Kalimdor_14(the map of orc starting zone all the way to orgrimmar).
I have modified R+D for usage in my project and when it tries to create the navmesh for this map it runs out of memory. I also tested this using the unmodified demo with same results.

I was thinking of generating the navmesh for each tile in this map, combining them and then saving them. Im not sure if this is a good approach or even possible...

----------


## namreeb

> Looks like Mikko is looking into 3D nav a lot lately too, namreeb. CF Digesting Duck: Loosely Ordered Mega Navigation Grids
> 
> Even if you're not actually based off of R+D these days, it might be educational to follow his thinking. I think that this idea of smaller "tiled" meshes fits a lot better with bot design, since the unwieldiness of giant "mega" meshes is one of the biggest problems I've faced trying to incorporate pathfinding into my bots, and since smaller tiles give a lot more opportunity for dynamically recalculating a mesh when navigability changes occur. Since I don't grind outside of instances, a lot of the optimizations that go into outdoors pathfinding are less than useless for me -- they obfuscate the data without benefiting me much. So, I'm curious to see where Mikko takes this new line of thought...


You can hardly scold me for not viewing a post he made just a few hours ago! That said, I actually had already read it (though it wasn't there when I made my previous post in this thread). I follow his blog religiously. My concern for this approach, which I believe is called a 2.5D nav mesh, is that there simply would be too much data to make it practical.

Edit: Yup, I asked that question on his blog and he just responded that that is indeed 2.5D. That approach can theoretically give you workable 3d navigation. You basically stack one tile on top of the other and another one on top of that, and then figure out a way to jump from one to the other. Too be accurate, you'd have to put let's say one tile per meter. That means to encompass a building like a cathedral you'd need to mesh the same ADT a few hundred times.




> Hopefully someone can answer this but what is the best solution to solve the size issue with the exported wow maps in R+D?
> 
> Ive used WoWMapper to export a full map, say Kalimdor_14(the map of orc starting zone all the way to orgrimmar).
> I have modified R+D for usage in my project and when it tries to create the navmesh for this map it runs out of memory. I also tested this using the unmodified demo with same results.
> 
> I was thinking of generating the navmesh for each tile in this map, combining them and then saving them. Im not sure if this is a good approach or even possible...


First, I assume by Kalimdor_14 you actually mean Kalimdor_14_yy.adt. Secondly, R+D shouldn't be running out of memory. You've probably got your cell size too low so its being waaay too precise. And as for one tile per adt, that is how I used to do it and it worked fine.

----------


## ostapus

Need help again (resolved my previous issue, it was indeed WMO rotation taken/stolen from wowmapper project). Now i am looking for help with M2 placements. As i understand from wiki, M2s which should be drawn refered in MCRF chunk of ADT/MCNK but offset i've got is always 0. If i am trying to draw interior's WMO M2s based on MODD chunk , there are too much junk M2. Anyone can provide some details on WMO's doodas proper handling ?

thanks

----------


## caytchen

> MCRF chunk of ADT/MCNK but offset i've got is always 0.


Look into the _obj files for each ADT.

----------


## ostapus

caytchen, can you provide another hint for me please because i am still missing interior's doodas ( i think).
modf.info.doodadSet for each wmo instance points to N doodas set being used in this wmo (found cases where # of doodas sets is less than reference, is that valid exception ?)
i am reading doodas sets in wmo root file, each set is defined by firstindex in modd file and # of entries starting from firstIndex.
next, during wmo processing i am doodas defined in doodas set[modf.info.doodadSet].
am i missing something ?

----------


## caytchen

> caytchen, can you provide another hint for me please because i am still missing interior's doodas ( i think).
> modf.info.doodadSet for each wmo instance points to N doodas set being used in this wmo (found cases where # of doodas sets is less than reference, is that valid exception ?)
> i am reading doodas sets in wmo root file, each set is defined by firstindex in modd file and # of entries starting from firstIndex.
> next, during wmo processing i am doodas defined in doodas set[modf.info.doodadSet].
> am i missing something ?


If you're only looking for WMO doodad sets, just do it as you laid out in your post: take the doodadSet from the WMO instance info, check if you actually have an doodad set for that index (there are some cases, as you said, where doodadSet is bigger than the actual number of doodad sets you have, just ignore those cases), and then just insert all doodads in the set when you're processing the WMO instance.
Just remember that interior doodads are transformed both by their parent WMOs transformation and their own.

----------


## dook123

http://img189.imageshack.us/img189/1...st5attempt.jpg

Yeah, some settings changed and better results. I would like to be able to figure out the best settings possible and calculate them on the fly per map.

Any suggestions on tile size and cell size according to map size? or should the tile size and cell size be the same for all wow maps?

----------


## ostapus

> If you're only looking for WMO doodad sets, just do it as you laid out in your post: take the doodadSet from the WMO instance info, check if you actually have an doodad set for that index (there are some cases, as you said, where doodadSet is bigger than the actual number of doodad sets you have, just ignore those cases), and then just insert all doodads in the set when you're processing the WMO instance.
> Just remember that interior doodads are transformed both by their parent WMOs transformation and their own.


 thanks.
doing exactly as you/me said and still missing doodas. Particular case is 
WORLD\\WMO\\KALIMDOR\\OGRIMMAR\\ORCHOVELORGRIMMAR.WMO - hut on the left of orgimar front gates, kalimdor_40_29. In the game this wmo has interior (shelf, couple barrels), but it has 0 doodasSet. However if i am drawing doodas referenced in MODR chunks - those doodas are present there + bunch of junk doodas. Same story if i render all doodas from MODN chunk of wmo instance - proper ones + bunch of junk.
However, this wmo has 5 doodas sets defined, and those are correct ones.. but why doodas set # in modf is 0?


---------- Post added at 10:44 AM ---------- Previous post was at 10:43 AM ----------




> http://img189.imageshack.us/img189/1...st5attempt.jpg
> 
> Yeah, some settings changed and better results. I would like to be able to figure out the best settings possible and calculate them on the fly per map.
> 
> Any suggestions on tile size and cell size according to map size? or should the tile size and cell size be the same for all wow maps?


yes, you can't dynamically change cs/ts, for each navmesh init you have to feed tiles with same cs/ts size. basically you decide once on cs and stick to it.

----------


## caytchen

> thanks.
> doing exactly as you/me said and still missing doodas. Particular case is 
> WORLD\\WMO\\KALIMDOR\\OGRIMMAR\\ORCHOVELORGRIMMAR.WMO - hut on the left of orgimar front gates, kalimdor_40_29. In the game this wmo has interior (shelf, couple barrels), but it has 0 doodasSet. However if i am drawing doodas referenced in MODR chunks - those doodas are present there + bunch of junk doodas. Same story if i render all doodas from MODN chunk of wmo instance - proper ones + bunch of junk.
> However, this wmo has 5 doodas sets defined, and those are correct ones.. but why doodas set # in modf is 0?


0 is a perfectly valid doodadSet index. It doesn't mean that it has no set at all.

----------


## ostapus

yes, but that set (which is always/mostly "Set_$DefaultGlobal") has 0 # doodads  :Frown: 

---------- Post added at 11:49 AM ---------- Previous post was at 11:44 AM ----------

ok, going to ask for favor, if someone can check kalimdor_40_29, the hut on the left of orgrimar gates (on the left if facing to the gates) has any interrior doodads (except one barrel which comes from general doodads for this adt)?
coz according to game view, sets 1 and 3 should be rendered (there are 2 instances of this wmo on that map, sets # 2,4 are junk sets), but again, set # in wmo info is 0

tia

update: fixed it, again modf structure info taken/stolen from wowmapper was incorrect (the size of flags is not int32 but rather in16)

----------


## cvccbum

Does anyone have an example or something to point me in the right direction on porting R&D to C#? I am not looking for a hand out, just not sure where to start. I have made the navmesh files, but am unsure how to read them correctly. I have looked at the R&D source and I see how they're doing it, I'm just stuck getting it to work in C#. Right now my bot is using a pathing system very similar to Pirox bot, and I would love to start using a navmesh instead. Any help is appreciated.

----------


## namreeb

Porting it to C# will be very painful. I believe if you search the R+D discussion group on google you will find a posting of someone who has done it. In my opinion it is better to write yourself a C++/CLI wrapper and expose the methods/data types which you will be needing. If you already have the code to generate your meshes (I'm assuming that code must be C++), then you can forget about all of Recast and need only expose a few methods in Detour. This has the added benefit of making it almost free to update your copy of R+D as Mikko makes changes to it.

----------


## dook123

Doing a C++ wrapper is the way to go as Namreeb has said, I currently use RD in C# this way and it works very well.

edit--

Any suggestions for cs/ts settings, I am getting zig zagging movement...

edit--

I was returning the wrong coords... oops -_-

----------


## amadmonk

Anyone keeping up with Mikko's recent (last few weeks) work to incorporate dynamic mesh changes?

I've been trying to avoid putting navigation information in my steering lib (and vice versa) and I'm wondering if anyone's keeping up on this as a possible "stay out of the fire" alternative.

----------


## namreeb

I have been following it religiously. Basically the process of making a mesh with Recast is as follows:

- Rasterize/voxelize input geometry
- Create span field
- Filter unwanted spans
- Build regions
- Merge regions
- Create contours
- Merge contours
- Extract triangles
- Merge triangles into convex polygons. This is your mesh.

Now, you can do the first three steps and still potentially add geometry. This is what Mikko is suggesting. Rather than meshing your terrain and saving the mesh, he is suggesting you perform steps one through three, and save those results. Then, when you are in-game you complete the meshing process. This gives you the opportunity to insert objects prior to completing the remaining steps.

Moreover, you can repeat the process easily as you still have your cached results for steps one through three of the bulk of your geometry.

It's also worth noting that time wise, step one I believe takes generally 50-75% of the overall build time. So while there are quite a few remaining steps, they go relatively quickly. Mikko's tests have him completing the remaining steps in approximately 20ms.





> Any suggestions for cs/ts settings, I am getting zig zagging movement...


I posted the settings I had been using with Recast a week or two ago. Just search.

----------


## dook123

> I posted the settings I had been using with Recast a week or two ago. Just search.


Funny how you overlook things, I have been over that page a couple times and missed it. Navmesh is currently working but I think I will test out your settings, I know I need to consider height and width of characters still.

----------


## namreeb

Mikko has just posted an update to his blog for those interested: Digesting Duck: First Iteration of Temporary Obstacles Checked In

----------


## amadmonk

Yeah, that was actually what prompted me to ask about it; it seems like he's getting close to having a working solution. Since I'm just a lazy leecher when it comes to nav stuff, I was wondering if any of the "big boys" were keeping up with Mikko's work on the topic  :Smile:  (last time I spoke with you about it, from what I remember, you weren't too impressed with the dynamic re-meshing method, but my memory sucks from too many years of abusing too many things).

----------


## namreeb

Well, he hasn't really changed anything here. There is no new math involved. He's just saying wait to do the last steps until you know about the new objects. That's one step up from just remeshing the whole thing. Meh, I'm not too impressed compared to Mikko's usual work. Seem like a bit of a cop out. He is continuing to investigate ways to do it more directly. So am I.  :Smile:  

That said, this approach does work.

----------


## Megamike55

> Below are the settings I used when I was using Recast. Note that, though its not specifically documented, many of these settings are dependent on the others. That is why I made up a few variables of my own and set the Recast parameters in terms of them. This way I don't have to remember the relationships. For example, the cell size must perfectly divide the tile size. Another example is you must provide at least enough geometry beyond the tile boundary to account for half of an agent width (I think).
> 
> For accuracy, you want to pick a cell size that will nicely divide your agent's radius and a height that will nicely divide your agent's height and maximum step size. By nicely I don't necessarily mean divide exactly, but close to it. The closer you are, the more accurate you will be. However, to exactly divide everything perfectly, you'll have a cell size so small that your meshes will be enormous.
> 
> As for tile size, the problem I had with Recast was that with large tiles you can get long and skinny mesh polygons. This can give you some non-optimal paths because of the string pulling algorithm being used in Detour at the time. This may or may not still be the case, but currently I am experimenting with MCNK sized tiles.
> 
> I think MaiN does either four or 16 tiles per ADT.
> 
> 
> ...


For anyone having as much trouble getting your nav mesh perfected as I am, here are some clarification questions that will hopefully help us (I have nav meshes generated for the whole world, but my navmeshes overlap badly and I end up with zig-zag movement between ADTs so I'm trying to fix that. I incorporated the information generously provided by namreeb but these are my questions to kind of get it all together in my head)
1) So you should provide about 10 or 11 world units of extra border geometry, right?
2) After providing the extra geometry,


```
	// Set the area where the navigation will be build.
	// Here the bounds of the input mesh are used, but the
	// area could be specified by an user defined box, etc.
	rcVcopy(m_cfg.bmin, bmin);
	rcVcopy(m_cfg.bmax, bmax);
	rcCalcGridSize(m_cfg.bmin, m_cfg.bmax, m_cfg.cs, &m_cfg.width, &m_cfg.height);
```

This bit of code (sorry if it is out of date a little, I don't constantly grab the latest Recast updates) should be set to restrict the bounds to the original ADT bounds, not inclusive of the extra geometry?
3) Terminology: Cell = what, exactly in Recast usage. Is it the dimensions of one voxel?
4) Terminology: Region = what, exactly in Recast usage. This one I never really understood.
5) I personally use a verts-per-poly of 3. This gives me only triangles to deal with, which at first was easier than allowing recast to do 4-6 verts per poly, then having to store / read and search within polys instead of simple triangles. Do other people do the same, who aren't using Detour?

I think that covers the areas I'm uncertain about. I'm especially unsure about question #2. EDIT: #2 - The more I think about it, the more I am certain that I have to set it as so. Could someone confirm this anyway?  :Smile:

----------


## namreeb

> 1) So you should provide about 10 or 11 world units of extra border geometry, right?
> 2) After providing the extra geometry,
> 
> 
> ```
> 	// Set the area where the navigation will be build.
> 	// Here the bounds of the input mesh are used, but the
> 	// area could be specified by an user defined box, etc.
> 	rcVcopy(m_cfg.bmin, bmin);
> ...


1.) It depends. While that should be enough, its important to mention how you arrive at that value. You want to include at least two multiples of your defined agent radius. In other words, you want to leave enough room for the agent to walk around the outside edge of your tile.

2.) This should be answerable from the Recast settings I have provided. In short: bmin/bmax define the box of the tile, not the input geometry. That is, if you were to give Recast an entire ADT you could get back a tile for just a chunk of it by giving the appropriate bmin/bmax/etc. values.

3.) Cell is a voxel. See The Voxelization Process | CritterAI for a description of voxels. There are other pages on that site which have very helpful descriptions/graphics of the process Recast uses.

4.) A region is a collection of spans in the height field which meet a certain criteria. The previously linked site has some information about this. Also useful for describing regions is a post pendra made on this forum some time ago:




> for y in height dimension
> for x in width dimension
> for span in cell at x,y
> if span is not already in a region
> if span has neighbor to the left, mark it same region as that one.
> else if span has neighbor above, mark it same region as that one
> else make it the first span in a new region
> end
> end
> end


5.) Two thoughts. Firstly, your mesh can always be broken into triangles regardless of your vertsPerPoly figure. This is what the detail mesh is. Secondly, Mikko has done some testing and found a vertsPerPoly of 6 to be generally optimal. See his slides on the process here: https://sites.google.com/site/recast...castSlides.pdf

For the verts per poly figure its the fifth or so slide from the bottom, but that pdf includes much more useful information besides that.

----------


## ostapus

i am storing compressed tile info addition to navigation data tiles ( 1 to 1, each nav data tile has corresponding compressed heightfield data) and when higher level nav function (the one which actually moves the character) detecting that character is stuck (time to travel from point a to b is greater than "supposed to be" time) - it will set temp obstacle object right ahead of character "stuck" point and regenerate affected tiles and path.

----------


## amadmonk

And... Mikko gave up (for now): Digesting Duck: My Recent Failures in Polygon Clipping

----------


## ostapus

well, that is pretty sad news. However despite requirements to keep large amount of intermediate data (compacted heightfield info) the current approach (regenerate tiles from precomputed/stored chf data) works pretty well. The size of chf data is roughly 3 times of navmesh data (ie, kalimdor + azeroth ~ 2gb) but i can live with that. :-)

----------


## amadmonk

I wouldn't be surprised if he keeps at it; he doesn't seem to be the kind of guy who just "gives up" on a problem. But with his recent posts, I was hopeful that he was nearing a general-purpose solution  :Smile:

----------


## QKdefus

hello, i was wondering if anyone had a clue why start zone for troll's / orc's seem to be missing in the obj file i created with wowmapper ? 
standing in those zone's return Kalimdor 14 wich is what ive used in wowmapper



thanks.

----------


## dook123

Looks like the troll starting island is not there, although it looks like its outlined. Maybe a glitch with wowmapper? Im not even sure that flowerew ever officially finished it...

----------


## TOM_RUS

> Looks like the troll starting island is not there, although it looks like its outlined. Maybe a glitch with wowmapper? Im not even sure that flowerew ever officially finished it...


May be because this zone uses a lot of phasing (and different phases stored in separate adt files as far I remember)...

----------


## dook123

That is an interesting point, I would consider it. Is there also some phasing in Dustwallow Marsh near Theramore?

 Theramore

----------


## QKdefus

ive been wondering if anyone else have countered or noticed the heavy ammount of missing doodad's while using wowmapper + R&D ? there's tons of tree's, huge rocks, burning bracier's, mailboxes etc etc it just seem to ignore totally. been testing this in various places such as new and old worlds with same result, where my toon gets stuck so much its not even funny.

anyone have experienced the same? or know any solution to this? 

also been trying to build "deepholm" for a couple days now with various id's such as mapID and areaID where a lot of the id's cause wowmapper to try build for hours to no end. but some id's actually produce a working obj file then again its missing quite a lot of doodad's as mentioned and tend to get stuck a lot.

thanks.

----------


## z0m

QKdefus,

are you maybe willing to share your Wrapper lib (C#)?

----------


## miceiken

https://github.com/WCell/WCell-Terrain
This might be of interest. It has a R&D C# wrapper. The project was made for WCell, a wow server emulator, but I guess it's the same logic as in a bot.

----------


## z0m

Perfect, thanks  :Smile: .

----------


## ostapus

> ive been wondering if anyone else have countered or noticed the heavy ammount of missing doodad's while using wowmapper + R&D ? there's tons of tree's, huge rocks, burning bracier's, mailboxes etc etc it just seem to ignore totally. been testing this in various places such as new and old worlds with same result, where my toon gets stuck so much its not even funny.
> 
> anyone have experienced the same? or know any solution to this? 
> 
> also been trying to build "deepholm" for a couple days now with various id's such as mapID and areaID where a lot of the id's cause wowmapper to try build for hours to no end. but some id's actually produce a working obj file then again its missing quite a lot of doodad's as mentioned and tend to get stuck a lot.
> 
> thanks.


those are dynamic objects (at least mailboxes, baziers, fire etc).. those ones are generated per server info in runtime.

----------


## QKdefus

ok i didnt think of that, just noticed same problem and thought of missing doodad's.. 
anyways main problem really are quite a few huge rocks and three's where small objects can be avoided with a simple unstuck routine





> QKdefus,
> 
> are you maybe willing to share your Wrapper lib (C#)?


unfortunately its not mine to share. but i belive that once its working properly overall, it will be released as a public navigation lib.

----------


## ostapus

> ok i didnt think of that, just noticed same problem and thought of missing doodad's.. 
> anyways main problem really are quite a few huge rocks and three's where small objects can be avoided with a simple unstuck routine
> 
> 
> 
> 
> unfortunately its not mine to share. but i belive that once its working properly overall, it will be released as a public navigation lib.


 detect "stuck", put obstacle between start point/end point, regenerate affected tiles, requery the path, profit.

----------


## QKdefus

problem is , theres rocks that can be cast through thus reender the traceline useless

----------


## ostapus

> problem is , theres rocks that can be cast through thus reender the traceline useless


 you split path to "steps", where each step takes ie 1 sec to complete.. say step starts at 1,1 and finished at 1.5,1.5. If within 3 sec you didnt get to end of step point - put obstacle from between your current position and end of step position.. then regenerate tiles/paths.. no traceline at all..

----------


## dook123

> .. then regenerate tiles/paths..


That can take awhile with large map sizes...

----------


## ostapus

> That can take awhile with large map sizes...


 you regenerate affected tiles (the ones affected by inserted obstacle), not whole map... in my case, i am using setting to have 16x16 tiles per ADT, in worst case (so far i saw it once maybe twice with pretty intensive testing) you have to regenerate 4 tiles - i didn't notice any visible slowdown.

----------


## QKdefus

the doodad's is really one of the smaller problem atm, i have this issue where the path just fails horrible on long path's as shown in the pictures





been trying to play around with the settings all day but it allways ends up like this.
(using tile 16x16 and cell size 0.50)

thanks

----------


## ostapus

check returning value from findpath, looks alike you just hit limit on number of path points/smoothpoints

----------


## guizmows

can someone show you your result fort Azeroth 32_48, 33_48 and 31_48.

I've really strange results depending on how I call wowmapper as shown by following pictures :


calling :


```

mainLaunch("world\\maps\\Azeroth\\Azeroth", -1, 31, 48, false, false, true);
mainLaunch("world\\maps\\Azeroth\\Azeroth", -1, 32, 48, false, false, true); 


```






```

mainLaunch("world\\maps\\Azeroth\\Azeroth", -1, 32, 48, false, false, true);
mainLaunch("world\\maps\\Azeroth\\Azeroth", -1, 31, 48, false, false, true); 


```




I just revert call order, and I obtain different result. I can't understand what may happen, can someone lead me in right direction plz.

----------


## PyGuy

I don't know for sure, but my guess is that the WMO reference for the wall that's missing is located in ADT 31_48 and that one or both processes is running out of memory before displaying it when the order is reversed.

----------


## JDBSOGTFO

i have a quick question would this work for swtor by any chance if not could someone convert it over to swtor for me and add it to the page i would be so grateful thanks  :Smile:

----------


## guizmows

R&D can work with any kind of game as long as you are able to extract the terrain geometrie

----------

