map.cpp 23 KB

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