/trunk/sources/utils/GraphViewer/Graph.cpp

# · C++ · 1038 lines · 823 code · 146 blank · 69 comment · 190 complexity · 4824be34091546e9906eec0112d796cd MD5 · raw file

  1. //-------------------------------------------------------------------------------------------------
  2. //
  3. //-------------------------------------------------------------------------------------------------
  4. //-------------------------------------------------------------------------------------------------
  5. #include "stdafx.h"
  6. #include "Graph.h"
  7. ///////////////////////////////////////////////////////////////////////////////////////////////////
  8. // game.graph
  9. ///////////////////////////////////////////////////////////////////////////////////////////////////
  10. //-------------------------------------------------------------------------------------------------
  11. CGraph::CGraph()
  12. {
  13. m_chFilename[0] = 0;
  14. m_pLevels = NULL;
  15. m_pVertexs = NULL;
  16. m_pEdges = NULL;
  17. m_pLevelPoints = NULL;
  18. m_pGrid = NULL;
  19. }
  20. //-------------------------------------------------------------------------------------------------
  21. CGraph::~CGraph()
  22. {
  23. Clean();
  24. }
  25. //-------------------------------------------------------------------------------------------------
  26. void CGraph::Clean()
  27. {
  28. m_chFilename[0] = 0;
  29. if (m_pLevels)
  30. {
  31. delete[] m_pLevels;
  32. m_pLevels = NULL;
  33. }
  34. if (m_pVertexs)
  35. {
  36. delete[] m_pVertexs;
  37. m_pVertexs = NULL;
  38. }
  39. if (m_pEdges)
  40. {
  41. delete[] m_pEdges;
  42. m_pEdges = NULL;
  43. }
  44. if (m_pLevelPoints)
  45. {
  46. delete[] m_pLevelPoints;
  47. m_pLevelPoints = NULL;
  48. }
  49. if (m_pGrid)
  50. {
  51. delete[] m_pGrid;
  52. m_pGrid = NULL;
  53. }
  54. }
  55. //-------------------------------------------------------------------------------------------------
  56. bool CGraph::Load(LPCSTR pFilename)
  57. {
  58. DWORD dwReaded;
  59. CString str;
  60. unsigned u;
  61. Clean();
  62. HANDLE hFile = CreateFile(pFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  63. if (hFile == INVALID_HANDLE_VALUE)
  64. {
  65. AfxMessageBox("ќшибка открыти€ файла!");
  66. Clean();
  67. return false;
  68. }
  69. // заголовок
  70. if (!ReadFile(hFile, &m_sHeader, sizeof(GG_HEADER), &dwReaded, NULL) || (dwReaded!=sizeof(GG_HEADER)))
  71. {
  72. AfxMessageBox("ќшибка чтени€ заголовка!");
  73. CloseHandle(hFile);
  74. Clean();
  75. return false;
  76. }
  77. // уровни
  78. if (m_sHeader.level_count <= 0)
  79. {
  80. AfxMessageBox("ќшибка: level_count <= 0");
  81. CloseHandle(hFile);
  82. Clean();
  83. return false;
  84. }
  85. m_pLevels = new GG_LEVEL[m_sHeader.level_count];
  86. if (!m_pLevels)
  87. {
  88. AfxMessageBox("ќшибка выделени€ пам€ти!");
  89. CloseHandle(hFile);
  90. Clean();
  91. return false;
  92. }
  93. for (u=0; u<m_sHeader.level_count; u++)
  94. {
  95. if (!LoadLevel(hFile, &m_pLevels[u]))
  96. {
  97. str.Format("ќшибка чтени€ уровн€ є%d", u);
  98. AfxMessageBox(str);
  99. CloseHandle(hFile);
  100. Clean();
  101. return false;
  102. }
  103. }
  104. // game vertex
  105. if (m_sHeader.vertex_count <= 0)
  106. {
  107. AfxMessageBox("ќшибка: vertex_count <= 0");
  108. CloseHandle(hFile);
  109. Clean();
  110. return false;
  111. }
  112. m_pVertexs = new GG_VERTEX[m_sHeader.vertex_count];
  113. if (!m_pVertexs)
  114. {
  115. AfxMessageBox("ќшибка выделени€ пам€ти!");
  116. CloseHandle(hFile);
  117. Clean();
  118. return false;
  119. }
  120. if (!ReadFile(hFile, m_pVertexs, m_sHeader.vertex_count*sizeof(GG_VERTEX), &dwReaded, NULL) || (dwReaded!=m_sHeader.vertex_count*sizeof(GG_VERTEX)))
  121. {
  122. AfxMessageBox("ќшибка чтени€ GG_VERTEX!");
  123. CloseHandle(hFile);
  124. Clean();
  125. return false;
  126. }
  127. // пересчитываем смещени€ в индексы
  128. unsigned edges_offset = m_sHeader.vertex_count * 0x2a;
  129. unsigned level_points_offset = edges_offset + m_sHeader.edge_count * 0x06;
  130. for (u=0; u<m_sHeader.vertex_count; u++)
  131. {
  132. if (m_pVertexs[u].edge_count > 0)
  133. m_pVertexs[u].edge_offset = (m_pVertexs[u].edge_offset - edges_offset) / 0x06;
  134. if (m_pVertexs[u].level_point_count > 0)
  135. m_pVertexs[u].level_point_offset = (m_pVertexs[u].level_point_offset - level_points_offset) / 0x14;
  136. }
  137. // edge
  138. if (m_sHeader.edge_count <= 0)
  139. {
  140. AfxMessageBox("ќшибка: edge_count <= 0");
  141. CloseHandle(hFile);
  142. Clean();
  143. return false;
  144. }
  145. m_pEdges = new GG_EDGE[m_sHeader.edge_count];
  146. if (!m_pEdges)
  147. {
  148. AfxMessageBox("ќшибка выделени€ пам€ти!");
  149. CloseHandle(hFile);
  150. Clean();
  151. return false;
  152. }
  153. if (!ReadFile(hFile, m_pEdges, m_sHeader.edge_count*sizeof(GG_EDGE), &dwReaded, NULL) || (dwReaded!=m_sHeader.edge_count*sizeof(GG_EDGE)))
  154. {
  155. AfxMessageBox("ќшибка чтени€ GG_EDGE!");
  156. CloseHandle(hFile);
  157. Clean();
  158. return false;
  159. }
  160. // level vertex
  161. if (m_sHeader.level_point_count > 0)
  162. {
  163. m_pLevelPoints = new GG_LEVEL_POINT[m_sHeader.level_point_count];
  164. if (!m_pLevelPoints)
  165. {
  166. AfxMessageBox("ќшибка выделени€ пам€ти!");
  167. CloseHandle(hFile);
  168. Clean();
  169. return false;
  170. }
  171. if (!ReadFile(hFile, m_pLevelPoints, m_sHeader.level_point_count*sizeof(GG_LEVEL_POINT), &dwReaded, NULL) || (dwReaded!=m_sHeader.level_point_count*sizeof(GG_LEVEL_POINT)))
  172. {
  173. AfxMessageBox("ќшибка чтени€ GG_LEVEL_POINT!");
  174. CloseHandle(hFile);
  175. Clean();
  176. return false;
  177. }
  178. }
  179. else
  180. {
  181. //AfxMessageBox("ќшибка: level_point_count <= 0");
  182. //CloseHandle(hFile);
  183. //Clean();
  184. //return false;
  185. }
  186. CloseHandle(hFile);
  187. strcpy(m_chFilename, pFilename);
  188. return true;
  189. }
  190. //-------------------------------------------------------------------------------------------------
  191. bool CGraph::LoadLevel(HANDLE hFile, GG_LEVEL* pLevel)
  192. {
  193. DWORD dwReaded;
  194. DWORD u=0;
  195. if (!ReadFile(hFile, &pLevel->level_name[u], 1, &dwReaded, NULL) || (dwReaded != 1))
  196. {
  197. AfxMessageBox("ќшибка при чтении имени уровн€!");
  198. return false;
  199. }
  200. while (pLevel->level_name[u++] != 0)
  201. {
  202. if (!ReadFile(hFile, &pLevel->level_name[u], 1, &dwReaded, NULL) || (dwReaded != 1))
  203. {
  204. AfxMessageBox("ќшибка при чтении имени уровн€!");
  205. return false;
  206. }
  207. }
  208. if (!ReadFile(hFile, &pLevel->offset, sizeof(POINT_3D), &dwReaded, NULL) || (dwReaded != sizeof(POINT_3D)))
  209. {
  210. AfxMessageBox("ќшибка при чтении смещени€ уровн€!");
  211. return false;
  212. }
  213. if (!ReadFile(hFile, &pLevel->level_id, 1, &dwReaded, NULL) || (dwReaded != 1))
  214. {
  215. AfxMessageBox("ќшибка при чтении id уровн€!");
  216. return false;
  217. }
  218. u=0;
  219. if (!ReadFile(hFile, &pLevel->section_name[u], 1, &dwReaded, NULL) || (dwReaded != 1))
  220. {
  221. AfxMessageBox("ќшибка при чтении секции уровн€!");
  222. return false;
  223. }
  224. while (pLevel->section_name[u++] != 0)
  225. {
  226. if (!ReadFile(hFile, &pLevel->section_name[u], 1, &dwReaded, NULL) || (dwReaded != 1))
  227. {
  228. AfxMessageBox("ќшибка при чтении секции уровн€!");
  229. return false;
  230. }
  231. }
  232. if (!ReadFile(hFile, &pLevel->guid, 16, &dwReaded, NULL) || (dwReaded != 16))
  233. {
  234. AfxMessageBox("ќшибка при чтении guid уровн€!");
  235. return false;
  236. }
  237. return true;
  238. }
  239. //-------------------------------------------------------------------------------------------------
  240. void CGraph::GridClean()
  241. {
  242. m_uGridCX = m_uGridCY = m_uGridCZ = 0;
  243. if (m_pGrid)
  244. {
  245. delete[] m_pGrid;
  246. m_pGrid = NULL;
  247. }
  248. }
  249. //-------------------------------------------------------------------------------------------------
  250. bool CGraph::GridInit(unsigned uLevel)
  251. {
  252. unsigned u, i, index, size, x, z, k;
  253. POINT_3D* ptr;
  254. unsigned level_id = m_pLevels[uLevel].level_id;
  255. // размерность матрицы по X и Z
  256. m_sGridBox.p1.x = m_sGridBox.p1.y = m_sGridBox.p1.z = 10000;
  257. m_sGridBox.p2.x = m_sGridBox.p2.y = m_sGridBox.p2.z = -10000;
  258. for (u=0; u<m_sHeader.vertex_count; u++)
  259. {
  260. if (m_pVertexs[u].level_id == level_id)
  261. {
  262. ptr = &m_pVertexs[u].level_point;
  263. if (m_sGridBox.p1.x > ptr->x)
  264. m_sGridBox.p1.x = ptr->x;
  265. if (m_sGridBox.p1.y > ptr->y)
  266. m_sGridBox.p1.y = ptr->y;
  267. if (m_sGridBox.p1.z > ptr->z)
  268. m_sGridBox.p1.z = ptr->z;
  269. if (m_sGridBox.p2.x < ptr->x)
  270. m_sGridBox.p2.x = ptr->x;
  271. if (m_sGridBox.p2.y < ptr->y)
  272. m_sGridBox.p2.y = ptr->y;
  273. if (m_sGridBox.p2.z < ptr->z)
  274. m_sGridBox.p2.z = ptr->z;
  275. index = m_pVertexs[u].level_point_offset;
  276. for (i=0; i<m_pVertexs[u].level_point_count; i++)
  277. {
  278. ptr = &m_pLevelPoints[index+i].point;
  279. if (m_sGridBox.p1.x > ptr->x)
  280. m_sGridBox.p1.x = ptr->x;
  281. if (m_sGridBox.p1.y > ptr->y)
  282. m_sGridBox.p1.y = ptr->y;
  283. if (m_sGridBox.p1.z > ptr->z)
  284. m_sGridBox.p1.z = ptr->z;
  285. if (m_sGridBox.p2.x < ptr->x)
  286. m_sGridBox.p2.x = ptr->x;
  287. if (m_sGridBox.p2.y < ptr->y)
  288. m_sGridBox.p2.y = ptr->y;
  289. if (m_sGridBox.p2.z < ptr->z)
  290. m_sGridBox.p2.z = ptr->z;
  291. }
  292. }
  293. }
  294. m_uGridCX = (unsigned) ((m_sGridBox.p2.x - m_sGridBox.p1.x) / 0.7 + 1.501);
  295. m_uGridCZ = (unsigned) ((m_sGridBox.p2.z - m_sGridBox.p1.z) / 0.7 + 1.501);
  296. // размерность матрицы по Y
  297. m_uGridCY = 1;
  298. size = m_uGridCX * m_uGridCZ;
  299. m_pGrid = new unsigned[size];
  300. if (!m_pGrid)
  301. {
  302. AfxMessageBox("ќшибка выделени€ пам€ти!");
  303. return false;
  304. }
  305. memset(m_pGrid, 0, size * sizeof(unsigned));
  306. for (u=0; u<m_sHeader.vertex_count; u++)
  307. {
  308. if (m_pVertexs[u].level_id == level_id)
  309. {
  310. ptr = &m_pVertexs[u].level_point;
  311. //x = (unsigned) ((ptr->x - m_sGridBox.p1.x) / 0.7 + 0.501);
  312. //z = (unsigned) ((ptr->z - m_sGridBox.p1.z) / 0.7 + 0.501);
  313. x = (unsigned) ((ptr->x - m_sGridBox.p1.x) / 0.7);
  314. z = (unsigned) ((ptr->z - m_sGridBox.p1.z) / 0.7);
  315. k = x * m_uGridCZ + z;
  316. m_pGrid[k]++;
  317. if (m_uGridCY < m_pGrid[k])
  318. m_uGridCY = m_pGrid[k];
  319. index = m_pVertexs[u].level_point_offset;
  320. for (i=0; i<m_pVertexs[u].level_point_count; i++)
  321. {
  322. ptr = &m_pLevelPoints[index+i].point;
  323. //x = (unsigned) ((ptr->x - m_sGridBox.p1.x) / 0.7 + 0.501);
  324. //z = (unsigned) ((ptr->z - m_sGridBox.p1.z) / 0.7 + 0.501);
  325. x = (unsigned) ((ptr->x - m_sGridBox.p1.x) / 0.7);
  326. z = (unsigned) ((ptr->z - m_sGridBox.p1.z) / 0.7);
  327. k = x * m_uGridCZ + z;
  328. m_pGrid[k]++;
  329. if (m_uGridCY < m_pGrid[k])
  330. m_uGridCY = m_pGrid[k];
  331. }
  332. }
  333. }
  334. delete[] m_pGrid;
  335. // заполнение матрицы индексами вертексов, дл€ game_vertex-ов ставим 1 в старший бит
  336. size = m_uGridCX * m_uGridCZ * m_uGridCY;
  337. m_pGrid = new unsigned[size];
  338. if (!m_pGrid)
  339. {
  340. AfxMessageBox("ќшибка выделени€ пам€ти!");
  341. return false;
  342. }
  343. memset(m_pGrid, -1, size * sizeof(unsigned));
  344. for (u=0; u<m_sHeader.vertex_count; u++)
  345. {
  346. if (m_pVertexs[u].level_id == level_id)
  347. {
  348. ptr = &m_pVertexs[u].level_point;
  349. //x = (unsigned) ((ptr->x - m_sGridBox.p1.x) / 0.7 + 0.501);
  350. //z = (unsigned) ((ptr->z - m_sGridBox.p1.z) / 0.7 + 0.501);
  351. x = (unsigned) ((ptr->x - m_sGridBox.p1.x) / 0.7);
  352. z = (unsigned) ((ptr->z - m_sGridBox.p1.z) / 0.7);
  353. k = (x * m_uGridCZ + z) * m_uGridCY;
  354. while (m_pGrid[k] != -1)
  355. k++;
  356. m_pGrid[k] = u | 0x80000000;
  357. index = m_pVertexs[u].level_point_offset;
  358. for (i=0; i<m_pVertexs[u].level_point_count; i++)
  359. {
  360. ptr = &m_pLevelPoints[index+i].point;
  361. //x = (unsigned) ((ptr->x - m_sGridBox.p1.x) / 0.7 + 0.501);
  362. //z = (unsigned) ((ptr->z - m_sGridBox.p1.z) / 0.7 + 0.501);
  363. x = (unsigned) ((ptr->x - m_sGridBox.p1.x) / 0.7);
  364. z = (unsigned) ((ptr->z - m_sGridBox.p1.z) / 0.7);
  365. k = (x * m_uGridCZ + z) * m_uGridCY;
  366. while (m_pGrid[k] != -1)
  367. k++;
  368. m_pGrid[k] = index+i;
  369. }
  370. }
  371. }
  372. return true;
  373. }
  374. //-------------------------------------------------------------------------------------------------
  375. void CGraph::DrawVertexs(DRAW_DATA* pDD)
  376. {
  377. if (!m_pVertexs || !m_pGrid)
  378. return;
  379. GG_VERTEX* ptr;
  380. int pt = ((pDD->iZoom < 3) ? 1 : pDD->iZoom / 2)+1; // размер точки
  381. COLORREF cr = RGB(0,192,0); // цвет точки
  382. unsigned i, v, gx, gy;
  383. for (unsigned x=0; x<(unsigned)pDD->cx; x++)
  384. {
  385. for (unsigned y=0; y<(unsigned)pDD->cy; y++)
  386. {
  387. gx = x + pDD->x;
  388. gy = (m_uGridCZ-1) - pDD->y - y;
  389. if ((gx < m_uGridCX) && (gy < m_uGridCZ))
  390. {
  391. i = (gx * m_uGridCZ + gy) * m_uGridCY;
  392. for (unsigned k=0; k<m_uGridCY; k++)
  393. {
  394. v = m_pGrid[i + k];
  395. if (v != -1)
  396. {
  397. if (v & 0x80000000)
  398. {
  399. ptr = &m_pVertexs[v & 0x7fffffff];
  400. if ((ptr->level_point.y >= pDD->fMinY) && (ptr->level_point.y <= pDD->fMaxY))
  401. {
  402. pDD->pDC->FillSolidRect(x*pDD->iZoom-1, y*pDD->iZoom-1, pt, pt, cr);
  403. break;
  404. }
  405. }
  406. }
  407. else
  408. {
  409. break;
  410. }
  411. }
  412. }
  413. }
  414. }
  415. }
  416. //-------------------------------------------------------------------------------------------------
  417. void CGraph::DrawEdges(DRAW_DATA* pDD)
  418. {
  419. if (!m_pEdges || !m_pGrid)
  420. return;
  421. GG_VERTEX* ptr;
  422. int pt = ((pDD->iZoom < 3) ? 1 : pDD->iZoom / 2)+3; // размер точки
  423. COLORREF cr = RGB(0,192,0); // цвет точки
  424. CPen pen(PS_SOLID, 1, cr);
  425. CPen* pOldPen = pDD->pDC->SelectObject(&pen);
  426. pDD->pDC->SetBkMode(OPAQUE);
  427. pDD->pDC->SetROP2(R2_COPYPEN);
  428. unsigned i, v, gx, gy;
  429. for (unsigned x=0; x<(unsigned)pDD->cx; x++)
  430. {
  431. for (unsigned y=0; y<(unsigned)pDD->cy; y++)
  432. {
  433. gx = x + pDD->x;
  434. gy = (m_uGridCZ-1) - pDD->y - y;
  435. if ((gx < m_uGridCX) && (gy < m_uGridCZ))
  436. {
  437. i = (gx * m_uGridCZ + gy) * m_uGridCY;
  438. for (unsigned k=0; k<m_uGridCY; k++)
  439. {
  440. v = m_pGrid[i + k];
  441. if (v != -1)
  442. {
  443. if (v & 0x80000000)
  444. {
  445. ptr = &m_pVertexs[v & 0x7fffffff];
  446. if ((ptr->level_point.y >= pDD->fMinY) && (ptr->level_point.y <= pDD->fMaxY))
  447. {
  448. for (unsigned l=0; l<m_pVertexs[v].edge_count; l++)
  449. {
  450. unsigned gvid = m_pEdges[m_pVertexs[v].edge_offset+l].game_vertex_id;
  451. if (m_pVertexs[v].level_id == m_pVertexs[gvid].level_id)
  452. {
  453. POINT_3D* pDst = &m_pVertexs[gvid].level_point;
  454. unsigned x2 = (unsigned) (abs((pDst->x - m_sGridBox.p1.x) / 0.7) - pDD->x);
  455. unsigned y2 = (unsigned) ((m_uGridCZ-1) - abs((pDst->z - m_sGridBox.p1.z) / 0.7) - pDD->y);
  456. pDD->pDC->MoveTo(x*pDD->iZoom, y*pDD->iZoom);
  457. pDD->pDC->LineTo(x2*pDD->iZoom, y2*pDD->iZoom);
  458. }
  459. else
  460. {
  461. pDD->pDC->FillSolidRect(x*pDD->iZoom-1, y*pDD->iZoom-1, pt, pt, cr);
  462. }
  463. }
  464. }
  465. }
  466. }
  467. else
  468. {
  469. break;
  470. }
  471. }
  472. }
  473. }
  474. }
  475. pDD->pDC->SelectObject(pOldPen);
  476. }
  477. //-------------------------------------------------------------------------------------------------
  478. void CGraph::DrawLevelPoints(DRAW_DATA* pDD)
  479. {
  480. if (!m_pLevelPoints || !m_pGrid)
  481. return;
  482. GG_LEVEL_POINT* ptr;
  483. int pt = 1;//(pDD->iZoom < 3) ? 1 : pDD->iZoom / 2; // размер точки
  484. COLORREF cr = RGB(0,0,92); // цвет точки
  485. unsigned i, v, gx, gy;
  486. for (unsigned x=0; x<(unsigned)pDD->cx; x++)
  487. {
  488. for (unsigned y=0; y<(unsigned)pDD->cy; y++)
  489. {
  490. gx = x + pDD->x;
  491. gy = (m_uGridCZ-1) - pDD->y - y;
  492. if ((gx < m_uGridCX) && (gy < m_uGridCZ))
  493. {
  494. i = (gx * m_uGridCZ + gy) * m_uGridCY;
  495. for (unsigned k=0; k<m_uGridCY; k++)
  496. {
  497. v = m_pGrid[i + k];
  498. if (v != -1)
  499. {
  500. if (!(v & 0x80000000))
  501. {
  502. ptr = &m_pLevelPoints[v];
  503. if ((ptr->point.y >= pDD->fMinY) && (ptr->point.y <= pDD->fMaxY))
  504. {
  505. pDD->pDC->FillSolidRect(x*pDD->iZoom, y*pDD->iZoom, pt, pt, cr);
  506. break;
  507. }
  508. }
  509. }
  510. else
  511. {
  512. break;
  513. }
  514. }
  515. }
  516. }
  517. }
  518. }
  519. //-------------------------------------------------------------------------------------------------
  520. void CGraph::DrawSelVertexs(DRAW_DATA* pDD, unsigned uVertex)
  521. {
  522. if (!m_pVertexs || !m_pGrid)
  523. return;
  524. GG_VERTEX* ptr = &m_pVertexs[uVertex & 0x7fffffff];
  525. int pt = ((pDD->iZoom < 3) ? 1 : pDD->iZoom / 2)+1; // размер точки
  526. COLORREF cr = RGB(192,0,0); // цвет точки
  527. unsigned x = (unsigned) (abs((ptr->level_point.x - m_sGridBox.p1.x) / 0.7) - pDD->x);
  528. unsigned y = (unsigned) ((m_uGridCZ-1) - abs((ptr->level_point.z - m_sGridBox.p1.z) / 0.7) - pDD->y);
  529. if ((ptr->level_point.y >= pDD->fMinY) && (ptr->level_point.y <= pDD->fMaxY))
  530. {
  531. pDD->pDC->FillSolidRect(x*pDD->iZoom-1, y*pDD->iZoom-1, pt, pt, cr);
  532. }
  533. }
  534. //-------------------------------------------------------------------------------------------------
  535. void CGraph::DrawSelEdges(DRAW_DATA* pDD, unsigned uVertex)
  536. {
  537. if (!m_pEdges || !m_pGrid)
  538. return;
  539. GG_VERTEX* ptr = &m_pVertexs[uVertex & 0x7fffffff];
  540. int pt = ((pDD->iZoom < 3) ? 1 : pDD->iZoom / 2)+3; // размер точки
  541. COLORREF cr = RGB(192,0,0); // цвет точки
  542. CPen pen(PS_SOLID, 1, cr);
  543. CPen* pOldPen = pDD->pDC->SelectObject(&pen);
  544. pDD->pDC->SetBkMode(OPAQUE);
  545. pDD->pDC->SetROP2(R2_COPYPEN);
  546. unsigned x = (unsigned) (abs((ptr->level_point.x - m_sGridBox.p1.x) / 0.7) - pDD->x);
  547. unsigned y = (unsigned) ((m_uGridCZ-1) - abs((ptr->level_point.z - m_sGridBox.p1.z) / 0.7) - pDD->y);
  548. if ((ptr->level_point.y >= pDD->fMinY) && (ptr->level_point.y <= pDD->fMaxY))
  549. {
  550. for (unsigned l=0; l<m_pVertexs[uVertex].edge_count; l++)
  551. {
  552. unsigned gvid = m_pEdges[m_pVertexs[uVertex].edge_offset+l].game_vertex_id;
  553. if (m_pVertexs[uVertex].level_id == m_pVertexs[gvid].level_id)
  554. {
  555. POINT_3D* pDst = &m_pVertexs[gvid].level_point;
  556. unsigned x2 = (unsigned) (abs((pDst->x - m_sGridBox.p1.x) / 0.7) - pDD->x);
  557. unsigned y2 = (unsigned) ((m_uGridCZ-1) - abs((pDst->z - m_sGridBox.p1.z) / 0.7) - pDD->y);
  558. pDD->pDC->MoveTo(x*pDD->iZoom, y*pDD->iZoom);
  559. pDD->pDC->LineTo(x2*pDD->iZoom, y2*pDD->iZoom);
  560. }
  561. else
  562. {
  563. pDD->pDC->FillSolidRect(x*pDD->iZoom-1, y*pDD->iZoom-1, pt, pt, cr);
  564. }
  565. }
  566. }
  567. pDD->pDC->SelectObject(pOldPen);
  568. }
  569. //-------------------------------------------------------------------------------------------------
  570. void CGraph::DrawSelLevelPoints(DRAW_DATA* pDD, unsigned uVertex)
  571. {
  572. if (!m_pLevelPoints || !m_pGrid)
  573. return;
  574. POINT_3D* ptr;
  575. int pt = 2;//(pDD->iZoom < 3) ? 2 : pDD->iZoom / 2 + 1; // размер точки
  576. COLORREF cr = RGB(192,0,0); // цвет точки
  577. if (uVertex & 0x80000000)
  578. {
  579. uVertex &= 0x7fffffff;
  580. unsigned index = m_pVertexs[uVertex].level_point_offset;
  581. for (unsigned i=0; i<m_pVertexs[uVertex].level_point_count; i++)
  582. {
  583. ptr = &m_pLevelPoints[index+i].point;
  584. unsigned x = (unsigned) (abs((ptr->x - m_sGridBox.p1.x) / 0.7) - pDD->x);
  585. unsigned y = (unsigned) ((m_uGridCZ-1) - abs((ptr->z - m_sGridBox.p1.z) / 0.7) - pDD->y);
  586. if ((ptr->y >= pDD->fMinY) && (ptr->y <= pDD->fMaxY))
  587. {
  588. pDD->pDC->FillSolidRect(x*pDD->iZoom, y*pDD->iZoom, pt, pt, cr);
  589. }
  590. }
  591. }
  592. else
  593. {
  594. ptr = &m_pLevelPoints[uVertex].point;
  595. unsigned x = (unsigned) (abs((ptr->x - m_sGridBox.p1.x) / 0.7) - pDD->x);
  596. unsigned y = (unsigned) ((m_uGridCZ-1) - abs((ptr->z - m_sGridBox.p1.z) / 0.7) - pDD->y);
  597. if ((ptr->y >= pDD->fMinY) && (ptr->y <= pDD->fMaxY))
  598. {
  599. pDD->pDC->FillSolidRect(x*pDD->iZoom, y*pDD->iZoom, pt, pt, cr);
  600. }
  601. }
  602. }
  603. ///////////////////////////////////////////////////////////////////////////////////////////////////
  604. // level.ai
  605. ///////////////////////////////////////////////////////////////////////////////////////////////////
  606. //-------------------------------------------------------------------------------------------------
  607. CLevel::CLevel()
  608. {
  609. m_chFilename[0] = 0;
  610. memset(&m_sHeader, 0, sizeof(AI_HEADER));
  611. m_pPoints = NULL;
  612. m_pGrid = NULL;
  613. }
  614. //-------------------------------------------------------------------------------------------------
  615. CLevel::~CLevel()
  616. {
  617. Clean();
  618. }
  619. //-------------------------------------------------------------------------------------------------
  620. void CLevel::Clean()
  621. {
  622. m_chFilename[0] = 0;
  623. memset(&m_sHeader, 0, sizeof(AI_HEADER));
  624. if (m_pPoints)
  625. {
  626. delete[] m_pPoints;
  627. m_pPoints = NULL;
  628. }
  629. if (m_pGrid)
  630. {
  631. delete[] m_pGrid;
  632. m_pGrid = NULL;
  633. }
  634. }
  635. //-------------------------------------------------------------------------------------------------
  636. bool CLevel::Load(LPCSTR pFilename)
  637. {
  638. DWORD dwReaded;
  639. Clean();
  640. HANDLE hFile = CreateFile(pFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  641. if (hFile == INVALID_HANDLE_VALUE)
  642. {
  643. AfxMessageBox("ќшибка открыти€ файла!");
  644. Clean();
  645. return false;
  646. }
  647. // заголовок
  648. if (!ReadFile(hFile, &m_sHeader, sizeof(AI_HEADER), &dwReaded, NULL) || (dwReaded!=sizeof(AI_HEADER)))
  649. {
  650. AfxMessageBox("ќшибка чтени€ заголовка!");
  651. CloseHandle(hFile);
  652. Clean();
  653. return false;
  654. }
  655. // вертексы
  656. if (m_sHeader.vertex_count <= 0)
  657. {
  658. AfxMessageBox("ќшибка: vertex_count <= 0");
  659. CloseHandle(hFile);
  660. Clean();
  661. return false;
  662. }
  663. m_pPoints = new AI_POINT[m_sHeader.vertex_count];
  664. if (!m_pPoints)
  665. {
  666. AfxMessageBox("ќшибка выделени€ пам€ти!");
  667. CloseHandle(hFile);
  668. Clean();
  669. return false;
  670. }
  671. if (!ReadFile(hFile, m_pPoints, m_sHeader.vertex_count*sizeof(AI_POINT), &dwReaded, NULL) || (dwReaded!=m_sHeader.vertex_count*sizeof(AI_POINT)))
  672. {
  673. AfxMessageBox("ќшибка чтени€ AI_POINT!");
  674. CloseHandle(hFile);
  675. Clean();
  676. return false;
  677. }
  678. CloseHandle(hFile);
  679. strcpy(m_chFilename, pFilename);
  680. return true;
  681. }
  682. //-------------------------------------------------------------------------------------------------
  683. void CLevel::GridClean()
  684. {
  685. m_uGridCX = m_uGridCY = m_uGridCZ = 0;
  686. if (m_pGrid)
  687. {
  688. delete[] m_pGrid;
  689. m_pGrid = NULL;
  690. }
  691. }
  692. //-------------------------------------------------------------------------------------------------
  693. bool CLevel::GridInit()
  694. {
  695. unsigned u, size, i;
  696. // размерность матрицы по X и Z
  697. m_uGridCX = (unsigned) ((m_sHeader.box.p2.x - m_sHeader.box.p1.x) / m_sHeader.cell_size + 1.501);
  698. m_uGridCZ = (unsigned) ((m_sHeader.box.p2.z - m_sHeader.box.p1.z) / m_sHeader.cell_size + 1.501);
  699. // размерность матрицы по Y
  700. m_uGridCY = 1;
  701. size = m_uGridCX * m_uGridCZ;
  702. m_pGrid = new unsigned[size];
  703. if (!m_pGrid)
  704. {
  705. AfxMessageBox("ќшибка выделени€ пам€ти!");
  706. return false;
  707. }
  708. memset(m_pGrid, 0, size * sizeof(unsigned));
  709. for (u=0; u<m_sHeader.vertex_count; u++)
  710. {
  711. i = m_pPoints[u].packed_xz;
  712. m_pGrid[i]++;
  713. if (m_pGrid[i] > (unsigned) m_uGridCY)
  714. m_uGridCY = m_pGrid[i];
  715. }
  716. delete[] m_pGrid;
  717. // заполнение матрицы индексами вертексов
  718. size = m_uGridCX * m_uGridCZ * m_uGridCY;
  719. m_pGrid = new unsigned[size];
  720. if (!m_pGrid)
  721. {
  722. AfxMessageBox("ќшибка выделени€ пам€ти!");
  723. return false;
  724. }
  725. memset(m_pGrid, -1, size * sizeof(unsigned));
  726. for (u=0; u<m_sHeader.vertex_count; u++)
  727. {
  728. i = m_pPoints[u].packed_xz * m_uGridCY;
  729. while (m_pGrid[i] != -1)
  730. i++;
  731. m_pGrid[i] = u;
  732. }
  733. return true;
  734. }
  735. //-------------------------------------------------------------------------------------------------
  736. void CLevel::DrawVertexs(DRAW_DATA* pDD)
  737. {
  738. if (!m_pPoints || !m_pGrid)
  739. return;
  740. float f;
  741. int pt = 1;//(pDD->iZoom < 3) ? 1 : pDD->iZoom / 2; // размер точки
  742. COLORREF cr = RGB(0,0,92); // цвет точки
  743. if (pDD->iCoverMode == 0)
  744. {
  745. unsigned i, v, gx, gy;
  746. for (unsigned x=0; x<(unsigned)pDD->cx; x++)
  747. {
  748. for (unsigned y=0; y<(unsigned)pDD->cy; y++)
  749. {
  750. gx = x + pDD->x;
  751. gy = (m_uGridCZ-1) - pDD->y - y;
  752. if ((gx < m_uGridCX) && (gy < m_uGridCZ))
  753. {
  754. i = (gx * m_uGridCZ + gy) * m_uGridCY;
  755. for (unsigned k=0; k<m_uGridCY; k++)
  756. {
  757. v = m_pGrid[i + k];
  758. if (v != -1)
  759. {
  760. f = m_sHeader.box.p1.y + (float) m_pPoints[v].packed_y * m_sHeader.factor_y / 65535;
  761. if ((f >= pDD->fMinY) && (f <= pDD->fMaxY))
  762. {
  763. pDD->pDC->FillSolidRect(x*pDD->iZoom, y*pDD->iZoom, pt, pt, cr);
  764. break;
  765. }
  766. }
  767. else
  768. {
  769. break;
  770. }
  771. }
  772. }
  773. }
  774. }
  775. }
  776. else
  777. {
  778. unsigned _cr[] = {
  779. RGB(0, 0,128),
  780. RGB(0, 32,128),
  781. RGB(0, 64,128),
  782. RGB(0,128,128),
  783. RGB( 0,128,64),
  784. RGB( 0,128,32),
  785. RGB( 0,128,0),
  786. RGB(32,128,0),
  787. RGB( 64,128,0),
  788. RGB(128,128,0),
  789. RGB(128, 64,0),
  790. RGB(128, 32,0),
  791. RGB(128,0,0),
  792. RGB(128,0,0),
  793. RGB(128,0,0),
  794. RGB(128,0,0)
  795. };
  796. unsigned _cr2[] = {
  797. RGB(0, 0,128),
  798. RGB(0, 16,128),
  799. RGB(0, 32,128),
  800. RGB(0, 64,128),
  801. RGB(0,128,128),
  802. RGB(0,128,64),
  803. RGB(0,128,32),
  804. RGB(0,128,16),
  805. RGB( 16,128,0),
  806. RGB( 32,128,0),
  807. RGB( 64,128,0),
  808. RGB(128,128,0),
  809. RGB(128,64,0),
  810. RGB(128,32,0),
  811. RGB(128,16,0),
  812. RGB(128, 0,0)
  813. };
  814. unsigned i, v, gx, gy, ugol;
  815. for (unsigned x=0; x<(unsigned)pDD->cx; x++)
  816. {
  817. for (unsigned y=0; y<(unsigned)pDD->cy; y++)
  818. {
  819. gx = x + pDD->x;
  820. gy = (m_uGridCZ-1) - pDD->y - y;
  821. if ((gx < m_uGridCX) && (gy < m_uGridCZ))
  822. {
  823. i = (gx * m_uGridCZ + gy) * m_uGridCY;
  824. for (unsigned k=0; k<m_uGridCY; k++)
  825. {
  826. v = m_pGrid[i + k];
  827. if (v != -1)
  828. {
  829. f = m_sHeader.box.p1.y + (float) m_pPoints[v].packed_y * m_sHeader.factor_y / 65535;
  830. if ((f >= pDD->fMinY) && (f <= pDD->fMaxY))
  831. {
  832. switch (pDD->iCoverMode)
  833. {
  834. case 1:
  835. pDD->pDC->FillSolidRect(x*pDD->iZoom, y*pDD->iZoom, pt, pt, _cr[m_pPoints[v].cover1]);
  836. break;
  837. case 2:
  838. pDD->pDC->FillSolidRect(x*pDD->iZoom, y*pDD->iZoom, pt, pt, _cr[m_pPoints[v].cover2]);
  839. break;
  840. case 3:
  841. pDD->pDC->FillSolidRect(x*pDD->iZoom, y*pDD->iZoom, pt, pt, _cr[m_pPoints[v].cover3]);
  842. break;
  843. case 4:
  844. pDD->pDC->FillSolidRect(x*pDD->iZoom, y*pDD->iZoom, pt, pt, _cr[m_pPoints[v].cover4]);
  845. break;
  846. //case 5:
  847. default:
  848. //перевод сферических координат в декартовы:
  849. // x = R*sin(Fi)*cos(Teta)
  850. // y = R*sin(Fi)*sin(Teta)
  851. // z = R*cos(Fi)
  852. //double pi = 3.1415926535;
  853. //double v = ((int)((pPoint->plane >> 7) & 0x03f)) * 0.5*pi / 64;
  854. //double u = ((int)((pPoint->plane >> 0) & 0x07f)) * 0.5*pi / 128;
  855. //double nx = sin(v)*cos(u);
  856. //double nz = sin(v)*sin(u);
  857. //double ny = cos(v);
  858. ugol = ((m_pPoints[v].plane >> 7) & 0x03f);
  859. if (ugol > 31)
  860. ugol = 31;
  861. pDD->pDC->FillSolidRect(x*pDD->iZoom, y*pDD->iZoom, pt, pt, _cr2[ugol/2]);
  862. break;
  863. };
  864. break;
  865. }
  866. }
  867. else
  868. {
  869. break;
  870. }
  871. }
  872. }
  873. }
  874. }
  875. }
  876. }
  877. //-------------------------------------------------------------------------------------------------
  878. void CLevel::DrawSelVertexs(DRAW_DATA* pDD, unsigned uVertex)
  879. {
  880. if (!m_pPoints || !m_pGrid)
  881. return;
  882. int pt = 2;//(pDD->iZoom < 3) ? 2 : pDD->iZoom / 2 + 1; // размер точки
  883. COLORREF cr = RGB(192,0,0); // цвет точки
  884. unsigned x = (m_pPoints[uVertex].packed_xz / m_uGridCZ) - pDD->x;
  885. unsigned y = (m_uGridCZ-1) - (m_pPoints[uVertex].packed_xz % m_uGridCZ) - pDD->y;
  886. float f = m_sHeader.box.p1.y + (float) m_pPoints[uVertex].packed_y * m_sHeader.factor_y / 65535;
  887. if ((f >= pDD->fMinY) && (f <= pDD->fMaxY))
  888. {
  889. pDD->pDC->FillSolidRect(x*pDD->iZoom, y*pDD->iZoom, pt, pt, cr);
  890. }
  891. }
  892. //-------------------------------------------------------------------------------------------------