map.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  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/asio.hpp>
  17. #include <boost/iostreams/filtering_streambuf.hpp>
  18. #include <boost/iostreams/copy.hpp>
  19. #include <boost/iostreams/filter/gzip.hpp>
  20. struct Map::impl
  21. {
  22. RaycastMesh *rm;
  23. };
  24. inline bool file_exists(const std::string& name) {
  25. std::ifstream f(name.c_str());
  26. return f.good();
  27. }
  28. ThreadReturnType LoadMapAsync(void* mapToLoad)
  29. {
  30. Map* map = (Map*)mapToLoad;
  31. map->SetMapLoaded(false);
  32. std::string filename = "Maps/";
  33. filename += map->GetFileName();
  34. std::string deflatedFileName = filename + ".EQ2MapDeflated";
  35. filename += ".EQ2Map";
  36. if(file_exists(deflatedFileName))
  37. filename = deflatedFileName;
  38. map->SetFileName(filename);
  39. if (map->Load(filename))
  40. map->SetMapLoaded(true);
  41. map->SetMapLoading(false);
  42. THREAD_RETURN(NULL);
  43. }
  44. Map::Map(string file, SPGrid* grid) {
  45. CheckMapMutex.SetName(file + "MapMutex");
  46. SetMapLoaded(false);
  47. m_ZoneFile = file;
  48. imp = nullptr;
  49. mGrid = grid;
  50. m_CellSize = CELLSIZEDEFAULT;
  51. }
  52. Map::~Map() {
  53. SetMapLoaded(false);
  54. if(imp) {
  55. imp->rm->release();
  56. safe_delete(imp);
  57. }
  58. }
  59. float Map::FindBestZ(glm::vec3 &start, glm::vec3 *result)
  60. {
  61. if (!IsMapLoaded())
  62. return BEST_Z_INVALID;
  63. if (!imp)
  64. return BEST_Z_INVALID;
  65. glm::vec3 tmp;
  66. if(!result)
  67. result = &tmp;
  68. start.z += 1.0f;//RuleI(Map, FindBestZHeightAdjust);
  69. glm::vec3 from(start.x, start.y, start.z);
  70. glm::vec3 to(start.x, start.y, BEST_Z_INVALID);
  71. float hit_distance;
  72. bool hit = false;
  73. hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
  74. if(hit) {
  75. return result->z;
  76. }
  77. // Find nearest Z above us
  78. to.z = -BEST_Z_INVALID;
  79. hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
  80. if (hit)
  81. {
  82. return result->z;
  83. }
  84. return BEST_Z_INVALID;
  85. }
  86. float Map::FindClosestZ(glm::vec3 &start, glm::vec3 *result) {
  87. if (!IsMapLoaded())
  88. return false;
  89. // Unlike FindBestZ, this method finds the closest Z value above or below the specified point.
  90. //
  91. if (!imp)
  92. return false;
  93. float ClosestZ = BEST_Z_INVALID;
  94. glm::vec3 tmp;
  95. if (!result)
  96. result = &tmp;
  97. glm::vec3 from(start.x, start.y, start.z);
  98. glm::vec3 to(start.x, start.y, BEST_Z_INVALID);
  99. float hit_distance;
  100. bool hit = false;
  101. // first check is below us
  102. hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
  103. if (hit) {
  104. ClosestZ = result->z;
  105. }
  106. // Find nearest Z above us
  107. to.z = -BEST_Z_INVALID;
  108. hit = imp->rm->raycast((const RmReal*)&from, (const RmReal*)&to, (RmReal*)result, nullptr, &hit_distance);
  109. if (hit) {
  110. if (std::abs(from.z - result->z) < std::abs(ClosestZ - from.z))
  111. return result->z;
  112. }
  113. return ClosestZ;
  114. }
  115. bool Map::LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) {
  116. if (!IsMapLoaded())
  117. return false;
  118. if(!imp)
  119. return false;
  120. return imp->rm->raycast((const RmReal*)&start, (const RmReal*)&end, (RmReal*)result, nullptr, nullptr);
  121. }
  122. bool Map::LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) {
  123. if (!IsMapLoaded())
  124. return false;
  125. if (!imp)
  126. return false;
  127. float z = BEST_Z_INVALID;
  128. glm::vec3 step;
  129. glm::vec3 cur;
  130. cur.x = start.x;
  131. cur.y = start.y;
  132. cur.z = start.z;
  133. step.x = end.x - start.x;
  134. step.y = end.y - start.y;
  135. step.z = end.z - start.z;
  136. float factor = step_mag / sqrt(step.x*step.x + step.y*step.y + step.z*step.z);
  137. step.x *= factor;
  138. step.y *= factor;
  139. step.z *= factor;
  140. int steps = 0;
  141. if (step.x > 0 && step.x < 0.001f)
  142. step.x = 0.001f;
  143. if (step.y > 0 && step.y < 0.001f)
  144. step.y = 0.001f;
  145. if (step.z > 0 && step.z < 0.001f)
  146. step.z = 0.001f;
  147. if (step.x < 0 && step.x > -0.001f)
  148. step.x = -0.001f;
  149. if (step.y < 0 && step.y > -0.001f)
  150. step.y = -0.001f;
  151. if (step.z < 0 && step.z > -0.001f)
  152. step.z = -0.001f;
  153. //while we are not past end
  154. //always do this once, even if start == end.
  155. while(cur.x != end.x || cur.y != end.y || cur.z != end.z)
  156. {
  157. steps++;
  158. glm::vec3 me;
  159. me.x = cur.x;
  160. me.y = cur.y;
  161. me.z = cur.z;
  162. glm::vec3 hit;
  163. float best_z = FindBestZ(me, &hit);
  164. float diff = best_z - z;
  165. diff = diff < 0 ? -diff : diff;
  166. if (z <= BEST_Z_INVALID || best_z <= BEST_Z_INVALID || diff < 12.0)
  167. z = best_z;
  168. else
  169. return true;
  170. //look at current location
  171. if(LineIntersectsZone(start, end, step_mag, result))
  172. {
  173. return true;
  174. }
  175. //move 1 step
  176. if (cur.x != end.x)
  177. cur.x += step.x;
  178. if (cur.y != end.y)
  179. cur.y += step.y;
  180. if (cur.z != end.z)
  181. cur.z += step.z;
  182. //watch for end conditions
  183. if ( (cur.x > end.x && end.x >= start.x) || (cur.x < end.x && end.x <= start.x) || (step.x == 0) ) {
  184. cur.x = end.x;
  185. }
  186. if ( (cur.y > end.y && end.y >= start.y) || (cur.y < end.y && end.y <= start.y) || (step.y == 0) ) {
  187. cur.y = end.y;
  188. }
  189. if ( (cur.z > end.z && end.z >= start.z) || (cur.z < end.z && end.z < start.z) || (step.z == 0) ) {
  190. cur.z = end.z;
  191. }
  192. }
  193. //walked entire line and didnt run into anything...
  194. return false;
  195. }
  196. bool Map::CheckLoS(glm::vec3 myloc, glm::vec3 oloc)
  197. {
  198. if (!IsMapLoaded())
  199. return false;
  200. if(!imp)
  201. return false;
  202. return !imp->rm->raycast((const RmReal*)&myloc, (const RmReal*)&oloc, nullptr, nullptr, nullptr);
  203. }
  204. // returns true if a collision happens
  205. bool Map::DoCollisionCheck(glm::vec3 myloc, glm::vec3 oloc, glm::vec3 &outnorm, float &distance) {
  206. if (!IsMapLoaded())
  207. return false;
  208. if(!imp)
  209. return false;
  210. return imp->rm->raycast((const RmReal*)&myloc, (const RmReal*)&oloc, nullptr, (RmReal *)&outnorm, (RmReal *)&distance);
  211. }
  212. Map *Map::LoadMapFile(std::string file, SPGrid* grid) {
  213. std::string filename = "Maps/";
  214. filename += file;
  215. std::string deflatedFileName = filename + ".EQ2MapDeflated";
  216. filename += ".EQ2Map";
  217. if(file_exists(deflatedFileName))
  218. filename = deflatedFileName;
  219. LogWrite(MAP__INFO, 7, "Map", "Attempting to load Map File [{%s}]", filename.c_str());
  220. auto m = new Map(file, grid);
  221. m->SetMapLoading(true);
  222. m->SetFileName(filename);
  223. #ifdef WIN32
  224. _beginthread(LoadMapAsync, 0, (void*)m);
  225. #else
  226. pthread_t t1;
  227. pthread_create(&t1, NULL, LoadMapAsync, (void*)m);
  228. pthread_detach(t1);
  229. #endif
  230. return m;
  231. }
  232. /**
  233. * @param filename
  234. * @return
  235. */
  236. bool Map::Load(const std::string &filename)
  237. {
  238. FILE *map_file = fopen(filename.c_str(), "rb");
  239. if (map_file) {
  240. LogWrite(MAP__INFO, 7, "Map", "Loading Map File [{%s}]", filename.c_str());
  241. bool loaded_map_file = LoadV2(map_file);
  242. fclose(map_file);
  243. if (loaded_map_file) {
  244. LogWrite(MAP__INFO, 7, "Map", "Loaded Map File [{%s}]", filename.c_str());
  245. }
  246. else {
  247. LogWrite(MAP__ERROR, 7, "Map", "FAILED Loading Map File [{%s}]", filename.c_str());
  248. }
  249. return loaded_map_file;
  250. }
  251. else {
  252. return false;
  253. }
  254. return false;
  255. }
  256. struct ModelEntry
  257. {
  258. struct Poly
  259. {
  260. uint32 v1, v2, v3;
  261. uint8 vis;
  262. };
  263. std::vector<glm::vec3> verts;
  264. std::vector<Poly> polys;
  265. };
  266. bool Map::LoadV2(FILE* f) {
  267. std::size_t foundDeflated = m_FileName.find(".EQ2MapDeflated");
  268. if(foundDeflated != std::string::npos)
  269. return LoadV2Deflated(f);
  270. // Read the string for the zone file name this was created for
  271. int8 strSize;
  272. char name[256];
  273. fread(&strSize, sizeof(int8), 1, f);
  274. LogWrite(MAP__DEBUG, 0, "Map", "strSize = %u", strSize);
  275. size_t len = fread(&name, sizeof(char), strSize, f);
  276. name[len] = '\0';
  277. LogWrite(MAP__DEBUG, 0, "Map", "name = %s", name);
  278. string fileName(name);
  279. std::size_t found = fileName.find(m_ZoneFile);
  280. // Make sure file contents are for the correct zone
  281. if (found == std::string::npos) {
  282. fclose(f);
  283. LogWrite(MAP__ERROR, 0, "Map", "Map::LoadV2() map contents (%s) do not match its name (%s).", &name, m_ZoneFile.c_str());
  284. return false;
  285. }
  286. // Read the min bounds
  287. fread(&m_MinX, sizeof(float), 1, f);
  288. fread(&m_MinZ, sizeof(float), 1, f);
  289. // Read the max bounds
  290. fread(&m_MaxX, sizeof(float), 1, f);
  291. fread(&m_MaxZ, sizeof(float), 1, f);
  292. // Calculate how many cells we need
  293. // in both the X and Z direction
  294. float width = m_MaxX - m_MinX;
  295. float height = m_MaxZ - m_MinZ;
  296. m_NumCellsX = ceil(width / m_CellSize);
  297. m_NumCellsZ = ceil(height / m_CellSize);
  298. if (mGrid != nullptr)
  299. mGrid->InitValues(m_MinX, m_MaxX, m_MinZ, m_MaxZ, m_NumCellsX, m_NumCellsZ);
  300. // Read the number of grids
  301. int32 NumGrids;
  302. fread(&NumGrids, sizeof(int32), 1, f);
  303. std::vector<glm::vec3> verts;
  304. std::vector<uint32> indices;
  305. uint32 face_count = 0;
  306. // Loop through the grids loading the face list
  307. for (int32 i = 0; i < NumGrids; i++) {
  308. // Read the grid id
  309. int32 GridID;
  310. fread(&GridID, sizeof(int32), 1, f);
  311. // Read the number of vertices
  312. int32 NumFaces;
  313. fread(&NumFaces, sizeof(int32), 1, f);
  314. face_count += NumFaces;
  315. // Loop through the vertices list reading
  316. // 3 at a time to creat a triangle (face)
  317. for (int32 y = 0; y < NumFaces; ) {
  318. // Each vertex need an x,y,z coordinate and
  319. // we will be reading 3 to create the face
  320. float x1, x2, x3;
  321. float y1, y2, y3;
  322. float z1, z2, z3;
  323. // Read the first vertex
  324. fread(&x1, sizeof(float), 1, f);
  325. fread(&y1, sizeof(float), 1, f);
  326. fread(&z1, sizeof(float), 1, f);
  327. y++;
  328. // Read the second vertex
  329. fread(&x2, sizeof(float), 1, f);
  330. fread(&y2, sizeof(float), 1, f);
  331. fread(&z2, sizeof(float), 1, f);
  332. y++;
  333. // Read the third (final) vertex
  334. fread(&x3, sizeof(float), 1, f);
  335. fread(&y3, sizeof(float), 1, f);
  336. fread(&z3, sizeof(float), 1, f);
  337. y++;
  338. glm::vec3 a(x1, z1, y1);
  339. glm::vec3 b(x2, z2, y2);
  340. glm::vec3 c(x3, z3, y3);
  341. size_t sz = verts.size();
  342. verts.push_back(a);
  343. indices.push_back((uint32)sz);
  344. verts.push_back(b);
  345. indices.push_back((uint32)sz + 1);
  346. verts.push_back(c);
  347. indices.push_back((uint32)sz + 2);
  348. if (mGrid != nullptr)
  349. {
  350. Face* face = new Face;
  351. face->Vertex1[0] = x1;
  352. face->Vertex1[1] = y1;
  353. face->Vertex1[2] = z1;
  354. face->Vertex2[0] = x2;
  355. face->Vertex2[1] = y2;
  356. face->Vertex2[2] = z2;
  357. face->Vertex3[0] = x3;
  358. face->Vertex3[1] = y3;
  359. face->Vertex3[2] = z3;
  360. mGrid->AddFace(face, GridID);
  361. }
  362. }
  363. }
  364. face_count = face_count / 3;
  365. if (imp) {
  366. imp->rm->release();
  367. imp->rm = nullptr;
  368. }
  369. else {
  370. imp = new impl;
  371. }
  372. imp->rm = createRaycastMesh((RmUint32)verts.size(), (const RmReal*)&verts[0], face_count, &indices[0]);
  373. if (!imp->rm) {
  374. delete imp;
  375. imp = nullptr;
  376. return false;
  377. }
  378. return true;
  379. }
  380. bool Map::LoadV2Deflated(FILE* f) {
  381. ifstream file(m_FileName.c_str(), ios_base::in | ios_base::binary);
  382. boost::iostreams::filtering_streambuf<boost::iostreams::input> inbuf;
  383. inbuf.push(boost::iostreams::gzip_decompressor());
  384. inbuf.push(file);
  385. ostream out(&inbuf);
  386. std::streambuf * const srcbuf = out.rdbuf();
  387. std::streamsize size = srcbuf->in_avail();
  388. if(size == -1)
  389. {
  390. LogWrite(MAP__ERROR, 0, "Map", "Map::LoadV2Deflated() unable to deflate (%s).", m_ZoneFile.c_str());
  391. return false;
  392. }
  393. // Read the string for the zone file name this was created for
  394. int8 strSize;
  395. char* buf = new char[1024];
  396. srcbuf->sgetn(buf,sizeof(int8));
  397. memcpy(&strSize,&buf[0],sizeof(int8));
  398. LogWrite(MAP__DEBUG, 0, "Map", "strSize = %u", strSize);
  399. char name[256];
  400. srcbuf->sgetn(&name[0],strSize);
  401. name[strSize] = '\0';
  402. LogWrite(MAP__DEBUG, 0, "Map", "name = %s", name);
  403. string fileName(name);
  404. std::size_t found = fileName.find(m_ZoneFile);
  405. // Make sure file contents are for the correct zone
  406. if (found == std::string::npos) {
  407. file.close();
  408. safe_delete_array(buf);
  409. LogWrite(MAP__ERROR, 0, "Map", "Map::LoadV2Deflated() map contents (%s) do not match its name (%s).", &name, m_ZoneFile.c_str());
  410. return false;
  411. }
  412. // Read the min bounds
  413. srcbuf->sgetn(buf,sizeof(float));
  414. memcpy(&m_MinX,&buf[0],sizeof(float));
  415. srcbuf->sgetn(buf,sizeof(float));
  416. memcpy(&m_MinZ,&buf[0],sizeof(float));
  417. srcbuf->sgetn(buf,sizeof(float));
  418. memcpy(&m_MaxX,&buf[0],sizeof(float));
  419. srcbuf->sgetn(buf,sizeof(float));
  420. memcpy(&m_MaxZ,&buf[0],sizeof(float));
  421. // Calculate how many cells we need
  422. // in both the X and Z direction
  423. float width = m_MaxX - m_MinX;
  424. float height = m_MaxZ - m_MinZ;
  425. m_NumCellsX = ceil(width / m_CellSize);
  426. m_NumCellsZ = ceil(height / m_CellSize);
  427. if (mGrid != nullptr)
  428. mGrid->InitValues(m_MinX, m_MaxX, m_MinZ, m_MaxZ, m_NumCellsX, m_NumCellsZ);
  429. // Read the number of grids
  430. int32 NumGrids;
  431. srcbuf->sgetn(buf,sizeof(int32));
  432. memcpy(&NumGrids,&buf[0],sizeof(int32));
  433. std::vector<glm::vec3> verts;
  434. std::vector<uint32> indices;
  435. uint32 face_count = 0;
  436. // Loop through the grids loading the face list
  437. for (int32 i = 0; i < NumGrids; i++) {
  438. // Read the grid id
  439. int32 GridID;
  440. srcbuf->sgetn(buf,sizeof(int32));
  441. memcpy(&GridID,&buf[0],sizeof(int32));
  442. // Read the number of vertices
  443. int32 NumFaces;
  444. srcbuf->sgetn(buf,sizeof(int32));
  445. memcpy(&NumFaces,&buf[0],sizeof(int32));
  446. face_count += NumFaces;
  447. // Loop through the vertices list reading
  448. // 3 at a time to creat a triangle (face)
  449. for (int32 y = 0; y < NumFaces; ) {
  450. // Each vertex need an x,y,z coordinate and
  451. // we will be reading 3 to create the face
  452. float x1, x2, x3;
  453. float y1, y2, y3;
  454. float z1, z2, z3;
  455. // Read the first vertex
  456. srcbuf->sgetn(buf,sizeof(float)*3);
  457. memcpy(&x1,&buf[0],sizeof(float));
  458. memcpy(&y1,&buf[4],sizeof(float));
  459. memcpy(&z1,&buf[8],sizeof(float));
  460. y++;
  461. // Read the second vertex
  462. srcbuf->sgetn(buf,sizeof(float)*3);
  463. memcpy(&x2,&buf[0],sizeof(float));
  464. memcpy(&y2,&buf[4],sizeof(float));
  465. memcpy(&z2,&buf[8],sizeof(float));
  466. y++;
  467. // Read the third (final) vertex
  468. srcbuf->sgetn(buf,sizeof(float)*3);
  469. memcpy(&x3,&buf[0],sizeof(float));
  470. memcpy(&y3,&buf[4],sizeof(float));
  471. memcpy(&z3,&buf[8],sizeof(float));
  472. y++;
  473. glm::vec3 a(x1, z1, y1);
  474. glm::vec3 b(x2, z2, y2);
  475. glm::vec3 c(x3, z3, y3);
  476. size_t sz = verts.size();
  477. verts.push_back(a);
  478. indices.push_back((uint32)sz);
  479. verts.push_back(b);
  480. indices.push_back((uint32)sz + 1);
  481. verts.push_back(c);
  482. indices.push_back((uint32)sz + 2);
  483. if (mGrid != nullptr)
  484. {
  485. Face* face = new Face;
  486. face->Vertex1[0] = x1;
  487. face->Vertex1[1] = y1;
  488. face->Vertex1[2] = z1;
  489. face->Vertex2[0] = x2;
  490. face->Vertex2[1] = y2;
  491. face->Vertex2[2] = z2;
  492. face->Vertex3[0] = x3;
  493. face->Vertex3[1] = y3;
  494. face->Vertex3[2] = z3;
  495. mGrid->AddFace(face, GridID);
  496. }
  497. }
  498. }
  499. face_count = face_count / 3;
  500. if (imp) {
  501. imp->rm->release();
  502. imp->rm = nullptr;
  503. }
  504. else {
  505. imp = new impl;
  506. }
  507. imp->rm = createRaycastMesh((RmUint32)verts.size(), (const RmReal*)&verts[0], face_count, &indices[0]);
  508. safe_delete_array(buf);
  509. if (!imp->rm) {
  510. delete imp;
  511. imp = nullptr;
  512. return false;
  513. }
  514. return true;
  515. }
  516. void Map::RotateVertex(glm::vec3 &v, float rx, float ry, float rz) {
  517. glm::vec3 nv = v;
  518. nv.y = (std::cos(rx) * v.y) - (std::sin(rx) * v.z);
  519. nv.z = (std::sin(rx) * v.y) + (std::cos(rx) * v.z);
  520. v = nv;
  521. nv.x = (std::cos(ry) * v.x) + (std::sin(ry) * v.z);
  522. nv.z = -(std::sin(ry) * v.x) + (std::cos(ry) * v.z);
  523. v = nv;
  524. nv.x = (std::cos(rz) * v.x) - (std::sin(rz) * v.y);
  525. nv.y = (std::sin(rz) * v.x) + (std::cos(rz) * v.y);
  526. v = nv;
  527. }
  528. void Map::ScaleVertex(glm::vec3 &v, float sx, float sy, float sz) {
  529. v.x = v.x * sx;
  530. v.y = v.y * sy;
  531. v.z = v.z * sz;
  532. }
  533. void Map::TranslateVertex(glm::vec3 &v, float tx, float ty, float tz) {
  534. v.x = v.x + tx;
  535. v.y = v.y + ty;
  536. v.z = v.z + tz;
  537. }