Path Generator – Recast/Detour and WowMapper – Step menu

User Tag List

Page 1 of 3 123 LastLast
Results 1 to 15 of 33
  1. #1
    RivaLfr's Avatar Contributor CoreCoins Purchaser Authenticator enabled
    Reputation
    221
    Join Date
    Sep 2010
    Posts
    258
    Thanks G/R
    2/25
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Path Generator – Recast/Detour and WowMapper – Step

    Path Generator – Recast/Detour and WowMapper – Step


    Hi there,

    After much time my path generator work fine, I am speaking little English, sorry if you not understand my text.

    For make a path generator you need:


    What is the step to make a generator of path?

    1. Dump all maps by tiled with WowMapper.
    2. Make mesh with recast/detour.
    3. Use the mesh with your program.


    1 - Dump all maps:

    Download the last WowMapper source code, look this post for more info of WowMapper for cataclysm: http://www.mmowned.com/forums/world-...h-creator.html.

    For dump all tile quickly I have edit the code of “Sample_D3dByAreaId.cpp”:
    Code:
    /** 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 <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 mainLaunch(std::string _zone_path,  int32_t _areaId, int32_t _xTile, int32_t _yTile, bool _dumpAll, bool _showMap, bool _saveTile) {
    	// 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(_zone_path);
    	mpq_h.getFile( zone_path + ".wdt", &file_buffer );
    
    	// Others Option
    	int32_t areaId = _areaId;
    	int32_t xTile = _xTile;
    	int32_t yTile = _yTile;
    	bool dumpAll = _dumpAll;
    	bool showMap = _showMap;
    	bool saveTile = _saveTile; // 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 && (areaId < 0 || xTile >= 0))
    	{
    		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 && (areaId < 0 || xTile >= 0))
    	{
    	  // Save to .obj Tile
    	  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 (saveTile && areaId >= 0)
    	{
    	  // Save to .obj AreaID
    	  std::stringstream fileName;
    	  fileName.clear();
    	  fileName << "dump\\" << areaId << ".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;
    }
    
    int main( int arch, char **argv ) 
    {
    	mainLaunch("world\\maps\\Expansion01\\Expansion01", -1, -1, -1, true, false, true);
    }
    
    //------------------------------------------------------------------------------
    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, "expansion3.MPQ" );
      loadMpq( mpq_h, "expansion2.MPQ" );
      loadMpq( mpq_h, "expansion1.MPQ" );
      loadMpq( mpq_h, "world.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, (void*)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, (void*)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;
    }
    Just edit this line to dump others continent:
    Code:
    mainLaunch("world\\maps\\Expansion01\\Expansion01", -1, -1, -1, true, false, true);
       
      // ( mainLaunch(std::string _zone_path,  int32_t _areaId, int32_t _xTile, int32_t _yTile, bool _dumpAll, bool _showMap, bool _saveTile)
       )
    These codes dump tiles to .obj file (YY_XX.obj).

    Info of the continents:
    Code:
      Azeroth > ZonzPath: "world\\maps\\Azeroth\\Azeroth"
      Kalimdor > ZonePath : "world\\maps\\Kalimdor\\Kalimdor"
      Outland > ZonePath : "world\\maps\\Expansion01\\Expansion01"
      Northrend > ZonePath : "world\\maps\\Northrend\\Northrend"
      Alterac Valley> ZonePath :” world\\maps\\PVPZone01\\PVPZone01”
      Warsong Gulch> ZonePath : world\\maps\\PVPZone03\\PVPZone03”
      Arathi Basin> ZonePath : “world\\mapsPVPZone04\\PVPZone04”
      Eye of the Storm> ZonePath : “world\\maps\\NetherstormBG\\NetherstormBG”
      Strand of the Ancients> ZonePath : "world\\maps\\NorthrendBG\\NorthrendBG”
      Isle of Conquest> ZonePath : “world\\maps\\IsleofConquest\\IsleofConquest”
      Twin Peaks> ZonePath : “world\\maps\\CataclysmCTF\\CataclysmCTF”
      Tol Barad> ZonePath : “world\\maps\\TolBarad\\TolBarad”
      The Battle for Gilneas > ZonePath : “world\\maps\\Gilneas_BG_2\\Gilneas_BG_2”

    2 - Obj to Mesh:

    My bot is on C#, Recast/Detour is on C++, for this reason I have make a Managed Dll, in this dll I have a unmanaged code (recast/detour), and I have a managed code for the class to create a mesh, and the class for create a path.

    I named my mesh with this format: ccc_yy_xx.mesh (c = continentId, y= Y, x = X)
    Continents Id Enum:
    Code:
          public enum ContinentId : uint
          {
              Northrend = 571,
              EOTS = 566,
              SOTA = 607,
              AV = 30,
              AB = 529,
              WSG = 489,
              Kalimdor = 1,
              Azeroth = 0,
          }
    My mesh config:
    Code:
              m_cellSize = 0.35f;
             m_cellHeight = 0.3f;
       
             m_agentHeight = 1.652778f;
             m_agentRadius = 0.2951389f;
             m_agentMaxClimb = 1.0f;
             m_agentMaxSlope = 50.0f;
       
             m_regionMinSize = 20;
             m_regionMergeSize = 40;
       
             m_edgeMaxLen = 12.0f;
             m_edgeMaxError = 1.3f;
       
             m_vertsPerPoly = 6.0f;
             m_detailSampleDist = 3.0f;
             m_detailSampleMaxError = 1.25f;
    And I make a NavMesh param (dtNavMeshParams) (for managed a tiled map)

    Code:
              navMeshParams.tileWidth = GRID_SIZE;
              navMeshParams.tileHeight = GRID_SIZE;
              navMeshParams.orig[0] = -(32*GRID_SIZE);
              navMeshParams.orig[1] = -(32*GRID_SIZE);
              navMeshParams.orig[2] = -(32*GRID_SIZE);
              navMeshParams.maxTiles =  5000;
              navMeshParams.maxPolys =  10000;
    Code:
    float GRID_SIZE = (533.0f + (1.0f / 3.0f));
    For save a mesh I use this code:
    Code:
    fwrite(m_navMesh->m_tiles->data, sizeof(unsigned char), navDataSize, file);
    For save a mesh param I use this code:
    Code:
    fwrite(&navMeshParams, sizeof(dtNavMeshParams), 1, fileParams);
    (Look the sample code of recast/detour to build a dtNavMesh)


    Use the mesh:

    Position on R/D is not same on Wow:
    Code:
      WoW -> R+D: -Y, Z, -X
      R+D -> WoW: -Z, -X, Y
    Sample code :
    Code:
      // Wow to R/D :
      m_spos[0] = -yStart;
      m_spos[1] = zStart;
      m_spos[2] = -xStart;
    
      // R/D to Wow:
      xStart = -(outPathTemps[2]);
      yStart= -(outPathTemps[0]);
      zStart = outPathTemps[1];
    For find the tiled by position I use this code:
    Code:
    // In C#:
      int tileX = (int)(((-(postion.X)) - (-(32 * GRID_SIZE))) / GRID_SIZE);
      int tileY = (int)(((-(postion.Y)) - (-(32 * GRID_SIZE))) / GRID_SIZE);
    For the continent id find in wow, He has a static address.

    For loading 1 (or more if the start position is not the same tiled of the end position) tile mesh, I use this code:
    Code:
    void PathFinderDt::LoadNavMesh(const char* filePath)
    {
        char fileName[512];
        FILE* file;
        if(!m_navMesh)
        {
    		cout << "Load NavMesh Params file " << "params.mesh" << endl;
            file = fopen("maps\\params.mesh", "rb");
    
            if(!file)
            {
    			cout << "Error: Could not open Mesh Params file > " << fileName << endl;
                return;
            }
    
            dtNavMeshParams params;
            unsigned int offset;
            fread(&params, sizeof(dtNavMeshParams), 1, file);
            fread(&offset, sizeof(unsigned int), 1, file);
            fclose(file);
    
            m_navMesh = dtAllocNavMesh();
    		
            if(!m_navMesh->init(&params))
            {
                delete m_navMesh;
                m_navMesh = 0;
    			cout << "Error: Failed to initialize Mesh Params file > " << fileName << endl;
                return;
            }
    		lastTileRef = 0;
        }
    
    	string tempMesh = string(filePath);
    	for (int i = 0 ; i <= countListMeshLoad - 1 ; i++)
    	{
    		if (tempMesh == listMeshLoad[i])
    		{
    			return;
    		}
    	}
    	countListMeshLoad++;
    	listMeshLoad[countListMeshLoad-1] = tempMesh;
    
    
        sprintf(fileName, "maps\\%s.mesh", filePath);
        file = fopen(fileName, "rb");
    
        if(!file)
        {
    		cout << "Error: Could not open Mesh data file > " << fileName << endl;
            return;
        }
    
        fseek(file, 0, SEEK_END);
        int length = ftell(file);
        fseek(file, 0, SEEK_SET);
    
        unsigned char* data =  (unsigned char*)dtAlloc(length, DT_ALLOC_PERM);
        fread(data, length, 1, file);
        fclose(file);
    
        dtMeshHeader* header = (dtMeshHeader*)data;
        if (header->magic != DT_NAVMESH_MAGIC)
        {
    		cout << "Error: has an invalid header > " << fileName << endl;
            dtFree(data);
            return;
        }
        if (header->version != DT_NAVMESH_VERSION)
        {
    		cout << "Error: Detour version is not correct > " << fileName << endl;
            dtFree(data);
            return;
        }
    
    	dtTileRef tileRef = 0;
    	dtMeshTile* te = (dtMeshTile*)data;
    	dtStatus dtResult = m_navMesh->addTile(data, length, DT_TILE_FREE_DATA, 0,  &tileRef);
        if(dtResult  != DT_SUCCESS)
        {
    		cout << "Error: could not load into navmesh  > " << fileName << endl;
            dtFree(data);
            return;
        }
    	if (!tileRef)
        {
        cout << "Error: could not load into navmesh  > " << fileName << endl;
        return;
        }
    
    	cout << "Loaded navmesh  > " << fileName << endl;
    }
    (For create a path look the sample code in recast/detour)
    ______________________________________


    This post is only for you help to make your path generator, I used this method, There are many other method, It is possible that I am doing some error, it's just a little text to help you.
    Last edited by RivaLfr; 01-31-2011 at 01:02 PM.

    Path Generator – Recast/Detour and WowMapper – Step
  2. Thanks Torpedoes (1 members gave Thanks to RivaLfr for this useful post)
  3. #2
    GameAssist's Avatar Banned CoreCoins Purchaser Authenticator enabled
    Reputation
    98
    Join Date
    Apr 2010
    Posts
    349
    Thanks G/R
    55/83
    Trade Feedback
    0 (0%)
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)
    The very idea of an automatic path generator stillborn)
    What is it?
    Your Вот will look for mobs to kill using an algorithm to find a way?
    and for this you need 10GB of useless unwrapped meshes?

  4. #3
    RivaLfr's Avatar Contributor CoreCoins Purchaser Authenticator enabled
    Reputation
    221
    Join Date
    Sep 2010
    Posts
    258
    Thanks G/R
    2/25
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    All mesh compresed have for size 500 mo. And I download tile by tile (If the palyer is in the zone and I need a mesh) (100 ko by tiled), is not excessive.

  5. #4
    GameAssist's Avatar Banned CoreCoins Purchaser Authenticator enabled
    Reputation
    98
    Join Date
    Apr 2010
    Posts
    349
    Thanks G/R
    55/83
    Trade Feedback
    0 (0%)
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)
    Yes it is clear that your meshes may be doing nothing in the program memory and that you used to hide the invisible sector - I do not mean it) What do you plan to use its technology to find your way?

  6. #5
    Millow's Avatar Member
    Reputation
    5
    Join Date
    Mar 2007
    Posts
    49
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thx a bunch Riva,

    When I have some free time, I will look into this.
    "What can be asserted without proof can be dismissed without proof." --- Christopher Hitchens

  7. #6
    crazyguymrkii's Avatar Private
    Reputation
    1
    Join Date
    Jan 2011
    Posts
    3
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by wlastas View Post
    The very idea of an automatic path generator stillborn)
    What is it?
    Your Вот will look for mobs to kill using an algorithm to find a way?
    and for this you need 10GB of useless unwrapped meshes?
    a nav mesh is an efficient way for a bot to tell where it is in the world and it can calculate the best way to get to where it needs to be (a mob, a quest giver, a poi, ect.)
    with a mesh you can do a lot of things, the first step to looking like a player is to be able to run dynamicaly to wherever you need to be. Once you set up logic to do a quet, you will need your bot to navigate around the world to complete its objectives.
    try googling Nav Mesh or search the forums for ppather to see what can be done once your bot can reliably navigate without waypoints or set paths.

  8. #7
    RivaLfr's Avatar Contributor CoreCoins Purchaser Authenticator enabled
    Reputation
    221
    Join Date
    Sep 2010
    Posts
    258
    Thanks G/R
    2/25
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    In the bot the navmesh is very useful, for win the time, and for make a good AI (if your character stuck all time for gather herb is not good for your wow account).

    recast/detour is very speed, the path is generated on less of one seconde.

  9. #8
    Kalle200000's Avatar Member
    Reputation
    1
    Join Date
    Jul 2008
    Posts
    19
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Really nice tut. Thanks

  10. #9
    miceiken's Avatar Contributor Authenticator enabled
    Reputation
    208
    Join Date
    Dec 2007
    Posts
    401
    Thanks G/R
    7/8
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Very nice guide, however I'm having a complication.
    TechSmith | Screencast.com, online video sharing, 2011-02-06_1813
    I get this while extracting Northrend with WowMapper. I've extracted Azeroth, Kalimdor and Expansion01 without any problems

  11. #10
    DarkLinux's Avatar Former Staff
    CoreCoins Purchaser Authenticator enabled
    Reputation
    1584
    Join Date
    May 2010
    Posts
    1,829
    Thanks G/R
    188/531
    Trade Feedback
    16 (100%)
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)
    This would have saved me around 62h of work. But it was fun getting by on my own. Thanks for the post! +Rep

  12. #11
    Nonal's Avatar Member
    Reputation
    3
    Join Date
    Sep 2008
    Posts
    17
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by DarkLinux View Post
    This would have saved me around 62h of work. But it was fun getting by on my own. Thanks for the post! +Rep
    By curiosity, is this guide or the use of Recast+Detour which would have saved you 62h of work ? Are you doing pathfinding through Recast ?
    I ask this because I am updating my code for cata. Path-finding, ADT parsing, etc... took me far too long on LK for too little rewards and I am
    currently inclined to move to 3rd party solutions and not to worry about weird axis, non-commutativity of rot matrix and pathfinding for the next century.
    But it was fun to do it by myself, indeed.

    Thanks,
    Last edited by Nonal; 02-06-2011 at 05:30 PM.

  13. #12
    DarkLinux's Avatar Former Staff
    CoreCoins Purchaser Authenticator enabled
    Reputation
    1584
    Join Date
    May 2010
    Posts
    1,829
    Thanks G/R
    188/531
    Trade Feedback
    16 (100%)
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)
    "Nonal"
    Well I was using stormlib to extract the files and that was a large amount of time. And then getting my head around Recast and Detour was also a long process. This guild would have help me with the extraction process only.


    Small question for RivaLfr, when I goto compile WowMapper I get an error saying that glm could not be found. It is not in the progject but is in the libs folder. My problem is that it will not compile with CMake. I get the error,

    Code:
    CMake Error at doc/CMakeLists.txt:10 (add_executable):
      add_executable called with incorrect number of arguments
    Could you post the c++ files for glm.

    Thanks!



    ----EDIT

    Downloaded The New glm and had no problems using cmake. But I don't think I need to compile it with cmake in the end... ops

    http://glm.g-truc.net/download.html
    Last edited by DarkLinux; 02-06-2011 at 07:31 PM.

  14. #13
    Nonal's Avatar Member
    Reputation
    3
    Join Date
    Sep 2008
    Posts
    17
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by DarkLinux View Post
    "Nonal"
    Well I was using stormlib to extract the files and that was a large amount of time. And then getting my head around Recast and Detour was also a long process. This guild would have help me with the extraction process only.
    Ok, that's what I wanted to know. I don't want to maintain my huge pile of code dealing with pre-cata file formats (which will ultimately change). If an external lib is doing for me, great !

    Thanks,

  15. #14
    Nonal's Avatar Member
    Reputation
    3
    Join Date
    Sep 2008
    Posts
    17
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Downloaded The New glm and had no problems using cmake. But I don't think I need to compile it with cmake in the end... ops
    Yes, I also ended up downloading glm to realize that GLM was mostly a template library, and that I was only requested to add an include path
    But as world is not fair to Linux, I had to spend time to port Windows specific parts to Linux. so long for K&R dream...

    There were some 64-bit issues as well:
    Code:
    struct MverChunk_s {
      char id[4];
      size_t size;
      char version[4];
    };
    looks like:

    Code:
    struct MverChunk_s {
      char id[4];
      uint32_t size;
      char version[4];
    };
    Arg. At least no struct packing issues. Let's see Recast tomorrow.

  16. #15
    DarkLinux's Avatar Former Staff
    CoreCoins Purchaser Authenticator enabled
    Reputation
    1584
    Join Date
    May 2010
    Posts
    1,829
    Thanks G/R
    188/531
    Trade Feedback
    16 (100%)
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)
    The glm was a simple 10 sec problem. But this one I don't get. In Sample_D3dAreaById's Header Files I am missing SDL.h, d3d9.h and d3dx9.h. Are they needed for anything? Because it will not compile with out it and it looks like its used in many structs and classes.

Page 1 of 3 123 LastLast

Similar Threads

  1. Recast/Detour - Mesh not generated inside of a tower - why?
    By Tanaris4 in forum WoW Memory Editing
    Replies: 24
    Last Post: 03-10-2012, 07:38 AM
  2. Pathing w/Recast + Detour - Potential issue - thoughts?
    By Tanaris4 in forum WoW Memory Editing
    Replies: 0
    Last Post: 12-12-2011, 10:41 AM
  3. Replies: 1
    Last Post: 12-12-2011, 02:31 AM
  4. [Link] C++ Recast/Detour Wrapper
    By Millow in forum WoW Memory Editing
    Replies: 11
    Last Post: 08-02-2011, 04:26 AM
  5. [Question] Detouring and calling SendPacket C++
    By Azzie2k8 in forum WoW Memory Editing
    Replies: 20
    Last Post: 01-06-2011, 08:58 AM
All times are GMT -5. The time now is 01:05 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search