Advertisement
Guest User

Untitled

a guest
Feb 10th, 2012
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.26 KB | None | 0 0
  1. #include "../src/mpqhandler_c.h"
  2. #include "../src/chunks/wdt/wdt_c.h"
  3. #include "../src/chunks/adt/adt_c.h"
  4.  
  5. /* This sample (which is actually code used by me) exports all tiles of a map
  6. * with a little border around it, its ADT x/y-position, the bounding box (border
  7. * excluded ofc!), vertices and indices. The meshes perfectly fit further
  8. * processing by recast. Hopy you like it. */
  9.  
  10. typedef std::map<uint32_t, uint32_t> IndexRemap_t;
  11. typedef std::pair<uint32_t, uint32_t> IndexPair_t;
  12.  
  13. // Basically outputs the whole mesh in one big one and gives you all tile positions
  14. void LoadAdts(const std::string &dir, const std::string &wdtDir,
  15. Mesh_c *bigMesh, AdtPos_t *adtPos);
  16.  
  17. // Retrieves a tile matching a bounding rect
  18. uint32_t GetTile(const Mesh_c &map, const Vec2_t &min,
  19. const Vec2_t &max, Mesh_c *mesh);
  20.  
  21. // no error handling on arguments passed
  22. int main(int argc, char **argv) {
  23. std::string mpq_dir("D:\\Games\\WoW\\Data"); // ex.: .
  24. std::string wdt_dir("World\\maps\\Azeroth\\Azeroth"); // ex.: World\\maps\\Azeroth\\Azeroth;
  25.  
  26. Mesh_c map;
  27. AdtPos_t adt_pos;
  28. // first load adts and meshes
  29. LoadAdts(mpq_dir, wdt_dir, &map, &adt_pos);
  30.  
  31. int count = 0;
  32. float tile_step = 533 + (1/3.0f);
  33. float border_width = tile_step/16;
  34. Vec2_t border(border_width, border_width);
  35.  
  36. for (AdtPos_t::iterator pos = adt_pos.begin();
  37. pos != adt_pos.end();
  38. ++pos, count++) {
  39. // assign bounding rect values
  40. Vec2_t min((pos->x-32)*tile_step, (pos->y-32)*tile_step);
  41. Vec2_t max(min.x+tile_step, min.y+tile_step);
  42. Vec2_t border_min(min - border);
  43. Vec2_t border_max(max + border);
  44.  
  45. Mesh_c mesh;
  46.  
  47. if (GetTile(map, border_min, border_max, &mesh)) {
  48. mesh.CalcBoundingBox();
  49. BBox_s bbox = mesh.bbox();
  50. bbox.min = Vec3_t(min.x, bbox.min.y-1.0f, min.y); // -1.0f for safetiness
  51. bbox.max = Vec3_t(max.x, bbox.max.y+1.0f, max.y); // +1.0f for safetiness
  52.  
  53. // Saving each tile to .obj Tile
  54. std::stringstream fileName;
  55. fileName.clear();
  56. fileName << "D:\\dump\\" << pos->x << "_" << pos->y << ".obj";
  57. std::cout << "Save to \"" << fileName.str() << "\" file." << std::endl;
  58. std::fstream fs1((const char*)(fileName.str().c_str()), std::fstream::out|std::fstream::binary);
  59. for (int i = 0; i < mesh.vertices().size(); i++)
  60. {
  61. fs1 << "v " << (mesh.vertices()[i].x) << ' ' << mesh.vertices()[i].y << ' ' << (mesh.vertices()[i].z) << '\n';
  62. }
  63. for (int i = 0; i < mesh.indices().size();)
  64. {
  65. fs1 << "f " << mesh.indices()[i++]+1;
  66. fs1 << ' ' << mesh.indices()[i++]+1;
  67. fs1 << ' ' << mesh.indices()[i++]+1 << '\n';
  68. }
  69.  
  70.  
  71. //// now we write the final mesh to a file: X_Y.mesh
  72. //std::stringstream ss;
  73. //ss << pos->x << "_" << pos->y << ".mesh";
  74. //std::fstream fs(ss.str().c_str(), std::fstream::out|std::fstream::binary);
  75.  
  76. //// print some info
  77. //std::cout << "Get tile: " << pos->x << "/" << pos->y << std::endl;
  78. //std::cout << "Min: " << min.x << "/" << min.y << std::endl;
  79. //std::cout << "Max: " << max.x << "/" << max.y << std::endl;
  80. //std::cout << "Write " << ss.str() << " to file" << std::endl << std::endl;
  81.  
  82. //// we export the bounding box ..
  83. //Header_s bb_head = { "BBX", sizeof(BBox_s) };
  84. //fs.write((char*)&bb_head, sizeof(bb_head));
  85. //fs.write((char*)&bbox, sizeof(BBox_s));
  86.  
  87. //// ... position ...
  88. //Header_s pos_head = { "POS", sizeof(AdtPos_s) };
  89. //fs.write((char*)&pos_head, sizeof(pos_head));
  90. //fs.write((char*)&(*pos), sizeof(AdtPos_s));
  91.  
  92. //// ... indices ...
  93. //wm_size_t idx_mem_size = sizeof(uint32_t)*mesh.indices().size();
  94. //Header_s idx_head = { "IDX", mesh.indices().size() };
  95. //fs.write((char*)&idx_head, sizeof(idx_head));
  96. //fs.write((char*)&mesh.indices()[0], idx_mem_size);
  97.  
  98. //// ... and vertices
  99. //wm_size_t vtx_mem_size = sizeof(Vec3_t)*mesh.vertices().size();
  100. //Header_s vtx_head = { "VTX", mesh.vertices().size() };
  101. //fs.write((char*)&vtx_head, sizeof(vtx_head));
  102. //fs.write((char*)&mesh.vertices()[0], vtx_mem_size);
  103.  
  104. //fs.close();
  105. }
  106. }
  107.  
  108. return 0;
  109. }
  110.  
  111. void LoadAdts(const std::string &dir, const std::string &wdtDir,
  112. Mesh_c *bigMesh, AdtPos_t *adtPos) {
  113. MpqHandler_c mpq_h(dir);
  114.  
  115. // load wdt to get all adt positions
  116. Buffer_t file_buf;
  117. mpq_h.LoadFile(wdtDir + ".wdt", &file_buf);
  118. Wdt_c wdt(&file_buf, wdtDir);
  119.  
  120. // start clock
  121. clock_t start = clock();
  122.  
  123. // copy adt positions for later use
  124. AdtPos_t::const_iterator pos_begin = wdt.adt_list().begin();
  125. AdtPos_t::const_iterator pos_end = wdt.adt_list().end();
  126. adtPos->resize(wdt.adt_list().size());
  127. std::copy(pos_begin, pos_end, adtPos->begin());
  128.  
  129. // size is for Azeroth without water, change it to bigger values to correctly
  130. // use it for other continents like Kalimdor
  131. Vertices_t vertices; vertices.reserve(23000000);
  132. Indices32_t indices; indices.reserve(105000000);
  133.  
  134. // unique identifiers to insert models only once and model_map
  135. Indices32_t uids;
  136. ModelMap_t model_map;
  137. int count = 0;
  138.  
  139. // start loading
  140. for (AdtPos_t::iterator pos = adtPos->begin(); pos != adtPos->end(); ++pos, count++) {
  141. Meshes_t meshes;
  142. meshes.reserve(10000);
  143.  
  144. std::stringstream adt_name;
  145. adt_name << wdtDir << "_" << pos->x << "_" << pos->y << ".adt";
  146.  
  147. mpq_h.LoadFile(adt_name.str(), &file_buf);
  148. std::cout << "Processing: (" << count+1 << ") " << adt_name.str() << " ";
  149. std::cout << file_buf.size()/1024 << " kb" << std::endl;
  150.  
  151. Adt_c adt(&file_buf, &uids, &model_map);
  152. adt.LoadWmos(mpq_h, false);
  153. adt.LoadDoodads(mpq_h, false);
  154.  
  155. meshes.push_back(Mesh_c());
  156. Mesh_c &terrain = meshes.back();
  157.  
  158. // adt meshes to vector
  159. adt.BuildTerrain(true, &terrain);
  160. adt.GetDoodads(&meshes);
  161. adt.GetWmos(&meshes, &meshes);
  162.  
  163. // merge meshes and add them into the buffer
  164. for (Meshes_t::const_iterator mesh = meshes.begin();
  165. mesh != meshes.end();
  166. ++mesh) {
  167. InsertIndices(mesh->indices(), vertices.size(), &indices);
  168.  
  169. Vertices_t mesh_vtx(mesh->vertices());
  170. TransformVertices(mesh->position(), mesh->rotation(), mesh->scale(),
  171. &mesh_vtx, 0, mesh_vtx.size());
  172.  
  173. vertices.insert(vertices.end(), mesh_vtx.begin(), mesh_vtx.end());
  174. }
  175. }
  176.  
  177. // cleanup modelmap
  178. for (ModelMap_t::iterator model = model_map.begin();
  179. model != model_map.end();
  180. ++model) {
  181. delete reinterpret_cast<Model_c*>(model->second);
  182. }
  183.  
  184.  
  185. std::cout << "Indices/vertices processed: " << indices.size() << "/";
  186. std::cout << vertices.size() << std::endl;
  187.  
  188. bigMesh->SetVertices(&vertices);
  189. bigMesh->SetIndices(&indices);
  190.  
  191. float time_needed = float(clock()-start)/CLOCKS_PER_SEC;
  192. std::cout << "Finished with ADTs after: " << time_needed;
  193. std::cout << " secs." << std::endl << std::endl;
  194. }
  195.  
  196. uint32_t GetTile(const Mesh_c &map, const Vec2_t &min,
  197. const Vec2_t &max, Mesh_c *mesh) {
  198. const Vertices_t &vtx = map.vertices();
  199. const Indices32_t &idx = map.indices();
  200.  
  201. IndexRemap_t remap;
  202. wm_size_t num_tris = idx.size()/3;
  203.  
  204. Vertices_t new_vtx;
  205. Indices32_t new_idx;
  206. uint32_t count = 0;
  207.  
  208. // used to filter vertices matching the bounding rect
  209. for (wm_size_t i = 0; i < num_tris; i++) {
  210. Vec3_t v[3];
  211. v[0] = vtx[idx[i*3+0]];
  212. v[1] = vtx[idx[i*3+1]];
  213. v[2] = vtx[idx[i*3+2]];
  214.  
  215. // look for vertices inside the bounding rect
  216. if (v[0].x >= min.x && v[0].x <= max.x && v[0].z >= min.y && v[0].z <= max.y &&
  217. v[1].x >= min.x && v[1].x <= max.x && v[1].z >= min.y && v[1].z <= max.y &&
  218. v[2].x >= min.x && v[2].x <= max.x && v[2].z >= min.y && v[2].z <= max.y) {
  219. // rearrange indices
  220. for (int j = 0; j < 3; j++) {
  221. IndexRemap_t::iterator found = remap.find(idx[i*3+j]);
  222. if (found == remap.end()) {
  223. remap.insert(IndexPair_t(idx[i*3+j], count));
  224. new_idx.push_back(count); // add new index
  225. new_vtx.push_back(v[j]); // add new vertex
  226. count++;
  227. } else {
  228. new_idx.push_back(found->second);
  229. }
  230. }
  231. }
  232. }
  233.  
  234. mesh->SetVertices(&new_vtx);
  235. mesh->SetIndices(&new_idx);
  236.  
  237. return count;
  238. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement