map.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983
  1. #include "map.h"
  2. #include "raycast_mesh.h"
  3. #include "../../common/Log.h"
  4. #ifdef WIN32
  5. #define _snprintf snprintf
  6. #include <WinSock2.h>
  7. #include <windows.h>
  8. #endif
  9. #include <algorithm>
  10. #include <map>
  11. #include <memory>
  12. #include <tuple>
  13. #include <vector>
  14. #include <fstream>
  15. #include <iostream>
  16. #include <boost/regex.hpp>
  17. #include <boost/filesystem.hpp>
  18. #include <boost/foreach.hpp>
  19. #include <boost/asio.hpp>
  20. #include <boost/iostreams/filtering_streambuf.hpp>
  21. #include <boost/iostreams/copy.hpp>
  22. #include <boost/iostreams/filter/gzip.hpp>
  23. struct Map::impl
  24. {
  25. RaycastMesh *rm;
  26. };
  27. inline bool file_exists(const std::string& name) {
  28. std::ifstream f(name.c_str());
  29. return f.good();
  30. }
  31. ThreadReturnType LoadMapAsync(void* mapToLoad)
  32. {
  33. Map* map = (Map*)mapToLoad;
  34. map->SetMapLoaded(false);
  35. std::string filename = "Maps/";
  36. filename += map->GetFileName();
  37. std::string deflatedFileName = filename + ".EQ2MapDeflated";
  38. filename += ".EQ2Map";
  39. if(file_exists(deflatedFileName))
  40. filename = deflatedFileName;
  41. map->SetFileName(filename);
  42. if (map->Load(filename))
  43. map->SetMapLoaded(true);
  44. map->SetMapLoading(false);
  45. THREAD_RETURN(NULL);
  46. }
  47. Map::Map(string zonename, string file) {
  48. CheckMapMutex.SetName(file + "MapMutex");
  49. SetMapLoaded(false);
  50. m_ZoneName = zonename;
  51. m_ZoneFile = file;
  52. imp = nullptr;
  53. m_MinY = 9999999.0f;
  54. m_MaxY = -9999999.0f;
  55. }
  56. Map::~Map() {
  57. SetMapLoaded(false);
  58. if(imp) {
  59. imp->rm->release();
  60. safe_delete(imp);
  61. }
  62. std::map<int32,GridMapBorder*>::iterator itr;
  63. for(itr = grid_map_border.begin(); itr != grid_map_border.end(); itr++) {
  64. safe_delete(itr->second);
  65. }
  66. grid_map_border.clear();
  67. }
  68. float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result, std::map<int32, bool>* ignored_widgets, uint32* GridID, uint32* WidgetID)
  69. {
  70. if (!IsMapLoaded())
  71. return BEST_Z_INVALID;
  72. if (!imp)
  73. return BEST_Z_INVALID;
  74. glm::vec3 tmp;
  75. if(!result)
  76. result = &tmp;
  77. start.z += 1.0f;//RuleI(Map, FindBestZHeightAdjust);
  78. glm::vec3 from(start.x, start.y, start.z);
  79. glm::vec3 to(start.x, start.y, BEST_Z_INVALID);
  80. float hit_distance;
  81. bool hit = false;
  82. hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance, (RmUint32*)GridID, (RmUint32*)WidgetID, (RmMap*)ignored_widgets);
  83. if(hit) {
  84. return result->z;
  85. }
  86. // Find nearest Z above us
  87. to.z = -BEST_Z_INVALID;
  88. hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance, (RmUint32*)GridID, (RmUint32*)WidgetID, (RmMap*)ignored_widgets);
  89. if (hit)
  90. {
  91. return result->z;
  92. }
  93. return BEST_Z_INVALID;
  94. }
  95. float Map::FindClosestZ(glm::vec3 &start, glm::vec3 *result, std::map<int32, bool>* ignored_widgets, uint32 *GridID, uint32* WidgetID) {
  96. if (!IsMapLoaded())
  97. return false;
  98. // Unlike FindBestZ, this method finds the closest Z value above or below the specified point.
  99. //
  100. if (!imp)
  101. return false;
  102. float ClosestZ = BEST_Z_INVALID;
  103. glm::vec3 tmp;
  104. if (!result)
  105. result = &tmp;
  106. glm::vec3 from(start.x, start.y, start.z);
  107. glm::vec3 to(start.x, start.y, BEST_Z_INVALID);
  108. float hit_distance;
  109. bool hit = false;
  110. // first check is below us
  111. hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance, (RmUint32*)GridID, (RmUint32*)WidgetID, (RmMap*)ignored_widgets);
  112. if (hit) {
  113. ClosestZ = result->z;
  114. }
  115. // Find nearest Z above us
  116. to.z = -BEST_Z_INVALID;
  117. hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance, (RmUint32*)GridID, (RmUint32*)WidgetID, (RmMap*)ignored_widgets);
  118. if (hit) {
  119. if (std::abs(from.z - result->z) < std::abs(ClosestZ - from.z))
  120. return result->z;
  121. }
  122. return ClosestZ;
  123. }
  124. bool Map::LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, std::map<int32, bool>* ignored_widgets, glm::vec3 *result) {
  125. if (!IsMapLoaded())
  126. return false;
  127. if(!imp)
  128. return false;
  129. return imp->rm->raycast((const RmReal*)&start, (const RmReal*)&end, (RmReal*)result, nullptr, nullptr, nullptr, nullptr, (RmMap*)ignored_widgets);
  130. }
  131. bool Map::LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, std::map<int32, bool>* ignored_widgets, glm::vec3 *result) {
  132. if (!IsMapLoaded())
  133. return false;
  134. if (!imp)
  135. return false;
  136. float z = BEST_Z_INVALID;
  137. glm::vec3 step;
  138. glm::vec3 cur;
  139. cur.x = start.x;
  140. cur.y = start.y;
  141. cur.z = start.z;
  142. step.x = end.x - start.x;
  143. step.y = end.y - start.y;
  144. step.z = end.z - start.z;
  145. float factor = step_mag / sqrt(step.x*step.x + step.y*step.y + step.z*step.z);
  146. step.x *= factor;
  147. step.y *= factor;
  148. step.z *= factor;
  149. int steps = 0;
  150. if (step.x > 0 && step.x < 0.001f)
  151. step.x = 0.001f;
  152. if (step.y > 0 && step.y < 0.001f)
  153. step.y = 0.001f;
  154. if (step.z > 0 && step.z < 0.001f)
  155. step.z = 0.001f;
  156. if (step.x < 0 && step.x > -0.001f)
  157. step.x = -0.001f;
  158. if (step.y < 0 && step.y > -0.001f)
  159. step.y = -0.001f;
  160. if (step.z < 0 && step.z > -0.001f)
  161. step.z = -0.001f;
  162. //while we are not past end
  163. //always do this once, even if start == end.
  164. while(cur.x != end.x || cur.y != end.y || cur.z != end.z)
  165. {
  166. steps++;
  167. glm::vec3 me;
  168. me.x = cur.x;
  169. me.y = cur.y;
  170. me.z = cur.z;
  171. glm::vec3 hit;
  172. float best_z = FindBestZ(me, &hit, ignored_widgets);
  173. float diff = best_z - z;
  174. diff = diff < 0 ? -diff : diff;
  175. if (z <= BEST_Z_INVALID || best_z <= BEST_Z_INVALID || diff < 12.0)
  176. z = best_z;
  177. else
  178. return true;
  179. //look at current location
  180. if(LineIntersectsZone(start, end, step_mag, ignored_widgets, result))
  181. {
  182. return true;
  183. }
  184. //move 1 step
  185. if (cur.x != end.x)
  186. cur.x += step.x;
  187. if (cur.y != end.y)
  188. cur.y += step.y;
  189. if (cur.z != end.z)
  190. cur.z += step.z;
  191. //watch for end conditions
  192. if ( (cur.x > end.x && end.x >= start.x) || (cur.x < end.x && end.x <= start.x) || (step.x == 0) ) {
  193. cur.x = end.x;
  194. }
  195. if ( (cur.y > end.y && end.y >= start.y) || (cur.y < end.y && end.y <= start.y) || (step.y == 0) ) {
  196. cur.y = end.y;
  197. }
  198. if ( (cur.z > end.z && end.z >= start.z) || (cur.z < end.z && end.z < start.z) || (step.z == 0) ) {
  199. cur.z = end.z;
  200. }
  201. }
  202. //walked entire line and didnt run into anything...
  203. return false;
  204. }
  205. bool Map::CheckLoS(glm::vec3 myloc, glm::vec3 oloc, std::map<int32, bool>* ignored_widgets)
  206. {
  207. if (!IsMapLoaded())
  208. return false;
  209. if(!imp)
  210. return false;
  211. return !imp->rm->raycast((const RmReal*)&myloc, (const RmReal*)&oloc, nullptr, nullptr, nullptr, nullptr, nullptr, (RmMap*)ignored_widgets);
  212. }
  213. // returns true if a collision happens
  214. bool Map::DoCollisionCheck(glm::vec3 myloc, glm::vec3 oloc, std::map<int32, bool>* ignored_widgets, glm::vec3 &outnorm, float &distance) {
  215. if (!IsMapLoaded())
  216. return false;
  217. if(!imp)
  218. return false;
  219. return imp->rm->raycast((const RmReal*)&myloc, (const RmReal*)&oloc, nullptr, (RmReal *)&outnorm, (RmReal *)&distance, nullptr, nullptr, (RmMap*)ignored_widgets);
  220. }
  221. Map *Map::LoadMapFile(std::string zonename, std::string file) {
  222. std::string filename = "Maps/";
  223. filename += file;
  224. std::string deflatedFileName = filename + ".EQ2MapDeflated";
  225. filename += ".EQ2Map";
  226. if(file_exists(deflatedFileName))
  227. filename = deflatedFileName;
  228. LogWrite(MAP__INFO, 7, "Map", "Attempting to load Map File [{%s}]", filename.c_str());
  229. auto m = new Map(zonename, file);
  230. m->SetMapLoading(true);
  231. m->SetFileName(filename);
  232. #ifdef WIN32
  233. _beginthread(LoadMapAsync, 0, (void*)m);
  234. #else
  235. pthread_t t1;
  236. pthread_create(&t1, NULL, LoadMapAsync, (void*)m);
  237. pthread_detach(t1);
  238. #endif
  239. return m;
  240. }
  241. /**
  242. * @param filename
  243. * @return
  244. */
  245. bool Map::Load(const std::string &filename)
  246. {
  247. FILE *map_file = fopen(filename.c_str(), "rb");
  248. if (map_file) {
  249. LogWrite(MAP__INFO, 7, "Map", "Loading Map File [{%s}]", filename.c_str());
  250. bool loaded_map_file = LoadV2(map_file);
  251. fclose(map_file);
  252. if (loaded_map_file) {
  253. LogWrite(MAP__INFO, 7, "Map", "Loaded Map File [{%s}]", filename.c_str());
  254. }
  255. else {
  256. LogWrite(MAP__ERROR, 7, "Map", "FAILED Loading Map File [{%s}]", filename.c_str());
  257. }
  258. return loaded_map_file;
  259. }
  260. else {
  261. return false;
  262. }
  263. return false;
  264. }
  265. struct ModelEntry
  266. {
  267. struct Poly
  268. {
  269. uint32 v1, v2, v3;
  270. uint8 vis;
  271. };
  272. std::vector<glm::vec3> verts;
  273. std::vector<Poly> polys;
  274. };
  275. bool Map::LoadV2(FILE* f) {
  276. std::size_t foundDeflated = m_FileName.find(".EQ2MapDeflated");
  277. if(foundDeflated != std::string::npos)
  278. return LoadV2Deflated(f);
  279. // Read the string for the zone file name this was created for
  280. int8 strSize;
  281. char name[256];
  282. fread(&strSize, sizeof(int8), 1, f);
  283. LogWrite(MAP__DEBUG, 0, "Map", "strSize = %u", strSize);
  284. size_t len = fread(&name, sizeof(char), strSize, f);
  285. name[len] = '\0';
  286. LogWrite(MAP__DEBUG, 0, "Map", "name = %s", name);
  287. string fileName(name);
  288. std::size_t found = fileName.find(m_ZoneName);
  289. // Make sure file contents are for the correct zone
  290. if (found == std::string::npos) {
  291. fclose(f);
  292. LogWrite(MAP__ERROR, 0, "Map", "Map::LoadV2() map contents (%s) do not match its name (%s).", &name, m_ZoneName.c_str());
  293. return false;
  294. }
  295. // Read the min bounds
  296. fread(&m_MinX, sizeof(float), 1, f);
  297. fread(&m_MinZ, sizeof(float), 1, f);
  298. // Read the max bounds
  299. fread(&m_MaxX, sizeof(float), 1, f);
  300. fread(&m_MaxZ, sizeof(float), 1, f);
  301. // Read the number of grids
  302. int32 NumGrids;
  303. fread(&NumGrids, sizeof(int32), 1, f);
  304. std::vector<glm::vec3> verts;
  305. std::vector<uint32> indices;
  306. std::vector<uint32> grids;
  307. std::vector<uint32> widgets;
  308. uint32 face_count = 0;
  309. // Loop through the grids loading the face list
  310. for (int32 i = 0; i < NumGrids; i++) {
  311. // Read the grid id
  312. int32 GridID;
  313. fread(&GridID, sizeof(int32), 1, f);
  314. // Read the number of vertices
  315. int32 NumFaces;
  316. fread(&NumFaces, sizeof(int32), 1, f);
  317. face_count += NumFaces;
  318. // Loop through the vertices list reading
  319. // 3 at a time to creat a triangle (face)
  320. GridMapBorder* border = GetMapGridBorder(GridID);
  321. for (int32 y = 0; y < NumFaces; ) {
  322. // Each vertex need an x,y,z coordinate and
  323. // we will be reading 3 to create the face
  324. float x1, x2, x3;
  325. float y1, y2, y3;
  326. float z1, z2, z3;
  327. // Read the first vertex
  328. fread(&x1, sizeof(float), 1, f);
  329. fread(&y1, sizeof(float), 1, f);
  330. fread(&z1, sizeof(float), 1, f);
  331. y++;
  332. // Read the second vertex
  333. fread(&x2, sizeof(float), 1, f);
  334. fread(&y2, sizeof(float), 1, f);
  335. fread(&z2, sizeof(float), 1, f);
  336. y++;
  337. // Read the third (final) vertex
  338. fread(&x3, sizeof(float), 1, f);
  339. fread(&y3, sizeof(float), 1, f);
  340. fread(&z3, sizeof(float), 1, f);
  341. y++;
  342. glm::vec3 a(x1, z1, y1);
  343. glm::vec3 b(x2, z2, y2);
  344. glm::vec3 c(x3, z3, y3);
  345. MapMinMaxY(y1);
  346. MapMinMaxY(y2);
  347. MapMinMaxY(y3);
  348. size_t sz = verts.size();
  349. verts.push_back(a);
  350. indices.push_back((uint32)sz);
  351. verts.push_back(b);
  352. indices.push_back((uint32)sz + 1);
  353. verts.push_back(c);
  354. indices.push_back((uint32)sz + 2);
  355. grids.push_back((uint32)GridID);
  356. widgets.push_back((uint32)0);
  357. MapGridMinMaxBorderArray(border, a, b, c);
  358. }
  359. }
  360. face_count = face_count / 3;
  361. if (imp) {
  362. imp->rm->release();
  363. imp->rm = nullptr;
  364. }
  365. else {
  366. imp = new impl;
  367. }
  368. imp->rm = createRaycastMesh((RmUint32)verts.size(), (const RmReal*)&verts[0], face_count, &indices[0], &grids[0], &widgets[0]);
  369. if (!imp->rm) {
  370. delete imp;
  371. imp = nullptr;
  372. return false;
  373. }
  374. return true;
  375. }
  376. bool Map::LoadV3Deflated(std::ifstream* file, std::streambuf * const srcbuf) {
  377. std::vector<glm::vec3> verts;
  378. std::vector<uint32> indices;
  379. std::vector<uint32> grids;
  380. std::vector<uint32> widgets;
  381. int8 strSize = 0;
  382. char* buf = new char[1024];
  383. int32 mapVersion = 0;
  384. srcbuf->sgetn(buf,sizeof(int32));
  385. memcpy(&mapVersion,&buf[0],sizeof(int32));
  386. LogWrite(MAP__DEBUG, 0, "Map", "MapVersion = %u", mapVersion);
  387. srcbuf->sgetn(buf,sizeof(int8));
  388. memcpy(&strSize,&buf[0],sizeof(int8));
  389. LogWrite(MAP__DEBUG, 0, "Map", "strSize = %u", strSize);
  390. char name[256];
  391. srcbuf->sgetn(&name[0],strSize);
  392. name[strSize] = '\0';
  393. LogWrite(MAP__DEBUG, 0, "Map", "name = %s", name);
  394. string fileName(name);
  395. std::size_t found = fileName.find(m_ZoneName);
  396. // Make sure file contents are for the correct zone
  397. if (found == std::string::npos) {
  398. file->close();
  399. safe_delete_array(buf);
  400. LogWrite(MAP__ERROR, 0, "Map", "Map::LoadV3Deflated() map contents (%s) do not match its name (%s).", &name, m_ZoneFile.c_str());
  401. return false;
  402. }
  403. // Read the min bounds
  404. srcbuf->sgetn(buf,sizeof(float));
  405. memcpy(&m_MinX,&buf[0],sizeof(float));
  406. srcbuf->sgetn(buf,sizeof(float));
  407. memcpy(&m_MinY,&buf[0],sizeof(float));
  408. srcbuf->sgetn(buf,sizeof(float));
  409. memcpy(&m_MinZ,&buf[0],sizeof(float));
  410. srcbuf->sgetn(buf,sizeof(float));
  411. memcpy(&m_MaxX,&buf[0],sizeof(float));
  412. srcbuf->sgetn(buf,sizeof(float));
  413. memcpy(&m_MaxY,&buf[0],sizeof(float));
  414. srcbuf->sgetn(buf,sizeof(float));
  415. memcpy(&m_MaxZ,&buf[0],sizeof(float));
  416. // Read the number of grids
  417. int32 NumGrids;
  418. srcbuf->sgetn(buf,sizeof(int32));
  419. memcpy(&NumGrids,&buf[0],sizeof(int32));
  420. uint32 face_count = 0;
  421. // Loop through the grids loading the face list
  422. for (int32 i = 0; i < NumGrids; i++) {
  423. // Read the grid id
  424. int32 GridID;
  425. srcbuf->sgetn(buf,sizeof(int32));
  426. memcpy(&GridID,&buf[0],sizeof(int32));
  427. // Read the number of vertices
  428. int32 vertex_map_count;
  429. srcbuf->sgetn(buf,sizeof(int32));
  430. memcpy(&vertex_map_count,&buf[0],sizeof(int32));
  431. GridMapBorder* border = GetMapGridBorder(GridID);
  432. for(int32 m = 0; m < vertex_map_count; m++) {
  433. int32 WidgetID;
  434. srcbuf->sgetn(buf,sizeof(int32));
  435. memcpy(&WidgetID,&buf[0],sizeof(int32));
  436. float w_x1, w_y1, w_z1;
  437. // read widget coords
  438. srcbuf->sgetn(buf,sizeof(float)*3);
  439. memcpy(&w_x1,&buf[0],sizeof(float));
  440. memcpy(&w_y1,&buf[4],sizeof(float));
  441. memcpy(&w_z1,&buf[8],sizeof(float));
  442. glm::vec3 a(w_x1, w_y1, w_z1);
  443. widget_map.insert(make_pair(WidgetID, a));
  444. int32 NumFaces;
  445. srcbuf->sgetn(buf,sizeof(int32));
  446. memcpy(&NumFaces,&buf[0],sizeof(int32));
  447. face_count += NumFaces;
  448. for (int32 y = 0; y < NumFaces; ) {
  449. // Each vertex need an x,y,z coordinate and
  450. // we will be reading 3 to create the face
  451. float x1, x2, x3;
  452. float y1, y2, y3;
  453. float z1, z2, z3;
  454. // Read the first vertex
  455. srcbuf->sgetn(buf,sizeof(float)*3);
  456. memcpy(&x1,&buf[0],sizeof(float));
  457. memcpy(&y1,&buf[4],sizeof(float));
  458. memcpy(&z1,&buf[8],sizeof(float));
  459. y++;
  460. // Read the second vertex
  461. srcbuf->sgetn(buf,sizeof(float)*3);
  462. memcpy(&x2,&buf[0],sizeof(float));
  463. memcpy(&y2,&buf[4],sizeof(float));
  464. memcpy(&z2,&buf[8],sizeof(float));
  465. y++;
  466. // Read the third (final) vertex
  467. srcbuf->sgetn(buf,sizeof(float)*3);
  468. memcpy(&x3,&buf[0],sizeof(float));
  469. memcpy(&y3,&buf[4],sizeof(float));
  470. memcpy(&z3,&buf[8],sizeof(float));
  471. y++;
  472. glm::vec3 a(x1, z1, y1);
  473. glm::vec3 b(x2, z2, y2);
  474. glm::vec3 c(x3, z3, y3);
  475. size_t sz = verts.size();
  476. verts.push_back(a);
  477. indices.push_back((uint32)sz);
  478. verts.push_back(b);
  479. indices.push_back((uint32)sz + 1);
  480. verts.push_back(c);
  481. indices.push_back((uint32)sz + 2);
  482. grids.push_back(GridID);
  483. widgets.push_back(WidgetID);
  484. MapGridMinMaxBorderArray(border, a, b, c);
  485. }
  486. }
  487. // Loop through the vertices list reading
  488. // 3 at a time to creat a triangle (face)
  489. }
  490. face_count = face_count / 3;
  491. if (imp) {
  492. imp->rm->release();
  493. imp->rm = nullptr;
  494. }
  495. else {
  496. imp = new impl;
  497. }
  498. imp->rm = createRaycastMesh((RmUint32)verts.size(), (const RmReal*)&verts[0], face_count, &indices[0], &grids[0], &widgets[0]);
  499. file->close();
  500. safe_delete_array(buf);
  501. if (!imp->rm) {
  502. delete imp;
  503. imp = nullptr;
  504. return false;
  505. }
  506. return true;
  507. }
  508. bool Map::LoadV2Deflated(FILE* f) {
  509. std::ifstream file(m_FileName.c_str(), ios_base::in | ios_base::binary);
  510. boost::iostreams::filtering_streambuf<boost::iostreams::input> inbuf;
  511. inbuf.push(boost::iostreams::gzip_decompressor());
  512. inbuf.push(file);
  513. ostream out(&inbuf);
  514. std::streambuf * const srcbuf = out.rdbuf();
  515. std::streamsize size = srcbuf->in_avail();
  516. if(size == -1)
  517. {
  518. file.close();
  519. LogWrite(MAP__ERROR, 0, "Map", "Map::LoadV2Deflated() unable to deflate (%s).", m_ZoneFile.c_str());
  520. return false;
  521. }
  522. // Read the string for the zone file name this was created for
  523. int8 strSize;
  524. char* buf = new char[1024];
  525. srcbuf->sgetn(buf,sizeof(int8));
  526. memcpy(&strSize,&buf[0],sizeof(int8));
  527. LogWrite(MAP__DEBUG, 0, "Map", "strSize = %u", strSize);
  528. char name[256];
  529. srcbuf->sgetn(&name[0],strSize);
  530. name[strSize] = '\0';
  531. LogWrite(MAP__DEBUG, 0, "Map", "name = %s", name);
  532. string fileName(name);
  533. if(fileName.find("EQ2EmuMapTool") != std::string::npos) {
  534. safe_delete_array(buf);
  535. return(LoadV3Deflated(&file, srcbuf));
  536. }
  537. std::size_t found = fileName.find(m_ZoneName);
  538. // Make sure file contents are for the correct zone
  539. if (found == std::string::npos) {
  540. file.close();
  541. safe_delete_array(buf);
  542. LogWrite(MAP__ERROR, 0, "Map", "Map::LoadV2Deflated() map contents (%s) do not match its name (%s).", &name, m_ZoneFile.c_str());
  543. return false;
  544. }
  545. // Read the min bounds
  546. srcbuf->sgetn(buf,sizeof(float));
  547. memcpy(&m_MinX,&buf[0],sizeof(float));
  548. srcbuf->sgetn(buf,sizeof(float));
  549. memcpy(&m_MinZ,&buf[0],sizeof(float));
  550. srcbuf->sgetn(buf,sizeof(float));
  551. memcpy(&m_MaxX,&buf[0],sizeof(float));
  552. srcbuf->sgetn(buf,sizeof(float));
  553. memcpy(&m_MaxZ,&buf[0],sizeof(float));
  554. // Read the number of grids
  555. int32 NumGrids;
  556. srcbuf->sgetn(buf,sizeof(int32));
  557. memcpy(&NumGrids,&buf[0],sizeof(int32));
  558. std::vector<glm::vec3> verts;
  559. std::vector<uint32> indices;
  560. std::vector<uint32> grids;
  561. std::vector<uint32> widgets;
  562. uint32 face_count = 0;
  563. // Loop through the grids loading the face list
  564. for (int32 i = 0; i < NumGrids; i++) {
  565. // Read the grid id
  566. int32 GridID;
  567. srcbuf->sgetn(buf,sizeof(int32));
  568. memcpy(&GridID,&buf[0],sizeof(int32));
  569. // Read the number of vertices
  570. int32 NumFaces;
  571. srcbuf->sgetn(buf,sizeof(int32));
  572. memcpy(&NumFaces,&buf[0],sizeof(int32));
  573. face_count += NumFaces;
  574. // Loop through the vertices list reading
  575. // 3 at a time to creat a triangle (face)
  576. GridMapBorder* border = GetMapGridBorder(GridID);
  577. for (int32 y = 0; y < NumFaces; ) {
  578. // Each vertex need an x,y,z coordinate and
  579. // we will be reading 3 to create the face
  580. float x1, x2, x3;
  581. float y1, y2, y3;
  582. float z1, z2, z3;
  583. // Read the first vertex
  584. srcbuf->sgetn(buf,sizeof(float)*3);
  585. memcpy(&x1,&buf[0],sizeof(float));
  586. memcpy(&y1,&buf[4],sizeof(float));
  587. memcpy(&z1,&buf[8],sizeof(float));
  588. y++;
  589. // Read the second vertex
  590. srcbuf->sgetn(buf,sizeof(float)*3);
  591. memcpy(&x2,&buf[0],sizeof(float));
  592. memcpy(&y2,&buf[4],sizeof(float));
  593. memcpy(&z2,&buf[8],sizeof(float));
  594. y++;
  595. // Read the third (final) vertex
  596. srcbuf->sgetn(buf,sizeof(float)*3);
  597. memcpy(&x3,&buf[0],sizeof(float));
  598. memcpy(&y3,&buf[4],sizeof(float));
  599. memcpy(&z3,&buf[8],sizeof(float));
  600. y++;
  601. glm::vec3 a(x1, z1, y1);
  602. glm::vec3 b(x2, z2, y2);
  603. glm::vec3 c(x3, z3, y3);
  604. MapMinMaxY(y1);
  605. MapMinMaxY(y2);
  606. MapMinMaxY(y3);
  607. size_t sz = verts.size();
  608. verts.push_back(a);
  609. indices.push_back((uint32)sz);
  610. verts.push_back(b);
  611. indices.push_back((uint32)sz + 1);
  612. verts.push_back(c);
  613. indices.push_back((uint32)sz + 2);
  614. grids.push_back(GridID);
  615. widgets.push_back((uint32)0);
  616. MapGridMinMaxBorderArray(border, a, b, c);
  617. }
  618. }
  619. face_count = face_count / 3;
  620. if (imp) {
  621. imp->rm->release();
  622. imp->rm = nullptr;
  623. }
  624. else {
  625. imp = new impl;
  626. }
  627. imp->rm = createRaycastMesh((RmUint32)verts.size(), (const RmReal*)&verts[0], face_count, &indices[0], &grids[0], &widgets[0]);
  628. file.close();
  629. safe_delete_array(buf);
  630. if (!imp->rm) {
  631. delete imp;
  632. imp = nullptr;
  633. return false;
  634. }
  635. return true;
  636. }
  637. void Map::RotateVertex(glm::vec3 &v, float rx, float ry, float rz) {
  638. glm::vec3 nv = v;
  639. nv.y = (std::cos(rx) * v.y) - (std::sin(rx) * v.z);
  640. nv.z = (std::sin(rx) * v.y) + (std::cos(rx) * v.z);
  641. v = nv;
  642. nv.x = (std::cos(ry) * v.x) + (std::sin(ry) * v.z);
  643. nv.z = -(std::sin(ry) * v.x) + (std::cos(ry) * v.z);
  644. v = nv;
  645. nv.x = (std::cos(rz) * v.x) - (std::sin(rz) * v.y);
  646. nv.y = (std::sin(rz) * v.x) + (std::cos(rz) * v.y);
  647. v = nv;
  648. }
  649. void Map::ScaleVertex(glm::vec3 &v, float sx, float sy, float sz) {
  650. v.x = v.x * sx;
  651. v.y = v.y * sy;
  652. v.z = v.z * sz;
  653. }
  654. void Map::TranslateVertex(glm::vec3 &v, float tx, float ty, float tz) {
  655. v.x = v.x + tx;
  656. v.y = v.y + ty;
  657. v.z = v.z + tz;
  658. }
  659. void Map::MapMinMaxY(float y) {
  660. if(y < m_MinY)
  661. m_MinY = y;
  662. if(y > m_MaxY)
  663. m_MaxY = y;
  664. }
  665. void Map::MapGridMinMaxBorderArray(GridMapBorder* border, glm::vec3 a, glm::vec3 b, glm::vec3 c) {
  666. if(!border)
  667. return;
  668. MapGridMinMaxBorder(border, a);
  669. MapGridMinMaxBorder(border, b);
  670. MapGridMinMaxBorder(border, c);
  671. }
  672. void Map::MapGridMinMaxBorder(GridMapBorder* border, glm::vec3 a) {
  673. if(!border)
  674. return;
  675. if(a.x < border->m_MinX)
  676. border->m_MinX = a.x;
  677. if(a.x > border->m_MaxX)
  678. border->m_MaxX = a.x;
  679. if(a.y < border->m_MinY)
  680. border->m_MinY = a.y;
  681. if(a.y > border->m_MaxY)
  682. border->m_MaxY = a.y;
  683. if(a.z < border->m_MinZ)
  684. border->m_MinZ = a.z;
  685. if(a.z > border->m_MaxZ)
  686. border->m_MaxZ = a.z;
  687. }
  688. bool Map::IsPointInGrid(GridMapBorder* border, glm::vec3 a, float radius) {
  689. return border != nullptr && (a.x >= (border->m_MinX - radius) && a.x <= (border->m_MaxX + radius) && a.y >= (border->m_MinY - radius) && a.y <= (border->m_MaxY + radius) && a.z >= (border->m_MinZ - radius) && a.z <= (border->m_MaxZ + radius));
  690. }
  691. std::vector<int32> Map::GetGridsByPoint(glm::vec3 a, float radius) {
  692. std::vector<int32> grids;
  693. std::map<int32,GridMapBorder*>::iterator itr;
  694. for(itr = grid_map_border.begin(); itr != grid_map_border.end(); itr++) {
  695. if(IsPointInGrid(itr->second, a, radius)) {
  696. grids.push_back(itr->first);
  697. }
  698. }
  699. return grids;
  700. }
  701. GridMapBorder* Map::GetMapGridBorder(int32 grid_id, bool instantiate_border) {
  702. std::map<int32,GridMapBorder*>::iterator itr = grid_map_border.find(grid_id);
  703. GridMapBorder* border = nullptr;
  704. if(itr != grid_map_border.end()) {
  705. border = itr->second;
  706. }
  707. else if(instantiate_border) {
  708. border = new GridMapBorder;
  709. border->m_MinX = 999999.0f;
  710. border->m_MaxX = -999999.0f;
  711. border->m_MinY = 999999.0f;
  712. border->m_MaxY = -999999.0f;
  713. border->m_MinZ = 999999.0f;
  714. border->m_MaxZ = -999999.0f;
  715. grid_map_border.insert(make_pair(grid_id, border));
  716. }
  717. return border;
  718. }
  719. void MapRange::AddVersionRange(std::string zoneName) {
  720. boost::filesystem::path targetDir("Maps/");
  721. // crash fix since the dir isn't present
  722. if(!boost::filesystem::is_directory(targetDir))
  723. {
  724. LogWrite(MAP__ERROR, 7, "Map", "Unable to find directory %s", targetDir.c_str());
  725. return;
  726. }
  727. boost::filesystem::recursive_directory_iterator iter(targetDir), eod;
  728. boost::smatch base_match;
  729. std::string formula = "(.*\\/|.*\\\\)((" + zoneName + ")(\\-([0-9]+)\\-([0-9]+))?)(\\.EQ2Map|\\.EQ2MapDeflated)$";
  730. boost::regex re(formula.c_str());
  731. LogWrite(MAP__INFO, 0, "Map", "Map Formula to match: %s", formula.c_str());
  732. BOOST_FOREACH(boost::filesystem::path
  733. const & i, make_pair(iter, eod)) {
  734. if (is_regular_file(i)) {
  735. std::string fileName(i.string());
  736. if (boost::regex_match(fileName, base_match, re)) {
  737. boost::ssub_match base_sub_match = base_match[2];
  738. boost::ssub_match base_sub_match2 = base_match[5];
  739. boost::ssub_match base_sub_match3 = base_match[6];
  740. std::string baseMatch(base_sub_match.str().c_str());
  741. std::string baseMatch2(base_sub_match2.str().c_str());
  742. std::string baseMatch3(base_sub_match3.str().c_str());
  743. LogWrite(MAP__INFO, 0, "Map", "Map To Load: %s, size: %i, string: %s, min: %s, max: %s\n", i.string().c_str(), base_match.size(), baseMatch.c_str(), baseMatch2.c_str(), baseMatch3.c_str());
  744. Map * zonemap = Map::LoadMapFile(zoneName, base_sub_match.str().c_str());
  745. int32 min_version = 0, max_version = 0;
  746. if (strlen(base_sub_match2.str().c_str()) > 0)
  747. min_version = atoul(base_sub_match2.str().c_str());
  748. if (strlen(base_sub_match2.str().c_str()) > 0)
  749. max_version = atoul(base_sub_match3.str().c_str());
  750. version_map.insert(std::make_pair(new VersionRange(min_version, max_version), zonemap));
  751. }
  752. }
  753. }
  754. }
  755. MapRange::MapRange()
  756. {
  757. }
  758. MapRange::~MapRange()
  759. {
  760. Clear();
  761. }
  762. void MapRange::Clear()
  763. {
  764. map<VersionRange*, Map*>::iterator itr;
  765. for (itr = version_map.begin(); itr != version_map.end(); itr++)
  766. {
  767. VersionRange* range = itr->first;
  768. Map* map = itr->second;
  769. delete range;
  770. delete map;
  771. }
  772. version_map.clear();
  773. }
  774. map<VersionRange*, Map*>::iterator MapRange::FindVersionRange(int32 min_version, int32 max_version)
  775. {
  776. map<VersionRange*, Map*>::iterator itr;
  777. for (itr = version_map.begin(); itr != version_map.end(); itr++)
  778. {
  779. VersionRange* range = itr->first;
  780. // if min and max version are both in range
  781. if (range->GetMinVersion() <= min_version && max_version <= range->GetMaxVersion())
  782. return itr;
  783. // if the min version is in range, but max range is 0
  784. else if (range->GetMinVersion() <= min_version && range->GetMaxVersion() == 0)
  785. return itr;
  786. // if min version is 0 and max_version has a cap
  787. else if (range->GetMinVersion() == 0 && max_version <= range->GetMaxVersion())
  788. return itr;
  789. }
  790. return version_map.end();
  791. }
  792. map<VersionRange*, Map*>::iterator MapRange::FindMapByVersion(int32 version)
  793. {
  794. map<VersionRange*, Map*>::iterator enditr = version_map.end();
  795. map<VersionRange*, Map*>::iterator itr;
  796. for (itr = version_map.begin(); itr != version_map.end(); itr++)
  797. {
  798. VersionRange* range = itr->first;
  799. // if min and max version are both in range
  800. if(range->GetMinVersion() == 0 && range->GetMaxVersion() == 0)
  801. enditr = itr;
  802. else if (version >= range->GetMinVersion() && version <= range->GetMaxVersion())
  803. return itr;
  804. }
  805. return enditr;
  806. }