Clone of PhatAC @ https://github.com/floaterxk/PhatAC

Polygon.cpp 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. #include "StdAfx.h"
  2. #include "Vertex.h"
  3. #include "Polygon.h"
  4. CVertexArray *CPolygon::pack_verts;
  5. CPolygon::CPolygon()
  6. {
  7. m_pVertexObjects = NULL;
  8. m_pVertexIndices = NULL;
  9. m_iPolyIndex = -1;
  10. m_iVertexCount = 0;
  11. m_iPolyType = 0;
  12. m_iCullType = 0;
  13. m_Face1_UVIndices = NULL;
  14. m_Face2_UVIndices = NULL;
  15. m_Face1_TexIndex = -1;
  16. m_Face2_TexIndex = -1;
  17. m_pVertexUnks = NULL;
  18. }
  19. CPolygon::~CPolygon()
  20. {
  21. Destroy();
  22. }
  23. void CPolygon::Destroy()
  24. {
  25. if (m_Face1_UVIndices)
  26. {
  27. delete[] m_Face1_UVIndices;
  28. m_Face1_UVIndices = NULL;
  29. }
  30. if (m_iCullType == 2)
  31. {
  32. if (m_Face2_UVIndices)
  33. {
  34. delete[] m_Face2_UVIndices;
  35. m_Face2_UVIndices = NULL;
  36. }
  37. }
  38. if (m_pVertexObjects)
  39. {
  40. delete[] m_pVertexObjects;
  41. m_pVertexObjects = NULL;
  42. }
  43. if (m_pVertexIndices)
  44. {
  45. delete[] m_pVertexIndices;
  46. m_pVertexIndices = NULL;
  47. }
  48. if (m_pVertexUnks)
  49. {
  50. delete[] m_pVertexUnks;
  51. m_pVertexUnks = NULL;
  52. }
  53. m_iVertexCount = 0;
  54. m_iPolyType = 0;
  55. m_Face1_TexIndex = -1;
  56. m_Face2_TexIndex = -1;
  57. m_iPolyIndex = -1;
  58. }
  59. void CPolygon::SetPackVerts(CVertexArray *Verts)
  60. {
  61. pack_verts = Verts;
  62. }
  63. BOOL CPolygon::UnPack(BYTE** ppData, ULONG iSize)
  64. {
  65. UNPACK(short, m_iPolyIndex);
  66. UNPACK(BYTE, m_iVertexCount);
  67. UNPACK(BYTE, m_iPolyType);
  68. UNPACK(DWORD, m_iCullType);
  69. UNPACK(short, m_Face1_TexIndex);
  70. UNPACK(short, m_Face2_TexIndex);
  71. m_pVertexObjects = new CSWVertex*[m_iVertexCount];
  72. m_pVertexIndices = new WORD[m_iVertexCount];
  73. m_pVertexUnks = new CSWVertex*[m_iVertexCount];
  74. for (DWORD i = 0; i < m_iVertexCount; i++)
  75. {
  76. WORD Index;
  77. UNPACK(WORD, Index);
  78. m_pVertexIndices[i] = Index;
  79. m_pVertexObjects[i] = (CSWVertex *)((BYTE *)pack_verts->m_pVertexBuffer + Index * CVertexArray::vertex_size);
  80. }
  81. if (!(m_iPolyType & 4))
  82. {
  83. m_Face1_UVIndices = new BYTE[m_iVertexCount];
  84. for (DWORD i = 0; i < m_iVertexCount; i++)
  85. UNPACK(BYTE, m_Face1_UVIndices[i]);
  86. }
  87. if ((m_iCullType == 2) && !(m_iPolyType & 8))
  88. {
  89. m_Face2_UVIndices = new BYTE[m_iVertexCount];
  90. for (DWORD i = 0; i < m_iVertexCount; i++)
  91. UNPACK(BYTE, m_Face2_UVIndices[i]);
  92. }
  93. if (m_iCullType == CullNone)
  94. {
  95. m_Face2_TexIndex = m_Face1_TexIndex;
  96. m_Face2_UVIndices = m_Face1_UVIndices;
  97. }
  98. #ifdef PRE_TOD
  99. PACK_ALIGN();
  100. #endif
  101. make_plane();
  102. return TRUE;
  103. }
  104. void CPolygon::make_plane()
  105. {
  106. // Not meant for human eyes.
  107. int i;
  108. CSWVertex *pPin;
  109. CSWVertex **ppSpread;
  110. Vector Norm(0, 0, 0);
  111. for (i = m_iVertexCount - 2, pPin = m_pVertexObjects[0], ppSpread = &m_pVertexObjects[1]; i > 0; i--, ppSpread++)
  112. {
  113. Vector V1 = ppSpread[0]->origin - pPin->origin;
  114. Vector V2 = ppSpread[1]->origin - pPin->origin;
  115. Norm = Norm + cross_product(V1, V2);
  116. }
  117. Norm.normalize();
  118. float distsum = 0;
  119. for (i = m_iVertexCount, ppSpread = m_pVertexObjects; i > 0; i--, ppSpread++)
  120. distsum += Norm.dot_product(ppSpread[0]->origin);
  121. m_plane.m_dist = -(distsum / m_iVertexCount);
  122. m_plane.m_normal = Norm;
  123. }
  124. BOOL CPolygon::polygon_hits_ray(const Ray& ray, float *time)
  125. {
  126. // return peafixed_polygon_hits_ray(ray, time);
  127. if (!m_iCullType && (m_plane.m_normal.dot_product(ray.m_direction) > 0))
  128. return FALSE;
  129. if (!m_plane.compute_time_of_intersection(ray, time))
  130. return FALSE;
  131. return point_in_polygon(ray.m_origin + (ray.m_direction * (*time)));
  132. }
  133. BOOL CPolygon::peafixed_polygon_hits_ray(const Ray& ray, float *depth)
  134. {
  135. if (!m_iCullType && (m_plane.m_normal.dot_product(ray.m_direction) > 0))
  136. return FALSE;
  137. float u, v;
  138. for (int i = 1; i < m_iVertexCount - 1;)
  139. {
  140. CSWVertex* CurrVertex1 = m_pVertexObjects[0];
  141. CSWVertex* CurrVertex2 = m_pVertexObjects[i];
  142. CSWVertex* CurrVertex3 = m_pVertexObjects[++i];
  143. if (D3DXIntersectTri(
  144. (D3DXVECTOR3 *)&CurrVertex1->origin,
  145. (D3DXVECTOR3 *)&CurrVertex2->origin,
  146. (D3DXVECTOR3 *)&CurrVertex3->origin,
  147. (D3DXVECTOR3 *)&ray.m_origin,
  148. (D3DXVECTOR3 *)&ray.m_direction,
  149. &u, &v, depth))
  150. return TRUE;
  151. }
  152. return FALSE;
  153. }
  154. BOOL CPolygon::point_in_polygon(const Vector& point)
  155. {
  156. CSWVertex* LastVertex = m_pVertexObjects[m_iVertexCount - 1];
  157. for (int i = 0; i < m_iVertexCount; i++)
  158. {
  159. CSWVertex* CurrVertex = m_pVertexObjects[i];
  160. Vector crossp =
  161. cross_product(m_plane.m_normal, CurrVertex->origin - LastVertex->origin);
  162. float dotp = crossp.dot_product(point - LastVertex->origin);
  163. if (dotp < 0.0)
  164. return FALSE;
  165. LastVertex = CurrVertex;
  166. }
  167. return TRUE;
  168. }
  169. //
  170. // For ray-tracing vertices -- something not in the client.
  171. //
  172. CSWVertex *PickVertexFromPolygon(CPolygon *pPoly, const Ray& ray)
  173. {
  174. if (!pPoly->m_iCullType && (pPoly->m_plane.m_normal.dot_product(ray.m_direction) > 0))
  175. return FALSE;
  176. float curr_depth = FLT_MAX;
  177. CSWVertex*
  178. result = NULL;
  179. for (int i = 1; i < pPoly->m_iVertexCount - 1;)
  180. {
  181. CSWVertex* CurrVertex1 = pPoly->m_pVertexObjects[0];
  182. CSWVertex* CurrVertex2 = pPoly->m_pVertexObjects[i];
  183. CSWVertex* CurrVertex3 = pPoly->m_pVertexObjects[++i];
  184. float u, v, depth;
  185. if (D3DXIntersectTri(
  186. (D3DXVECTOR3 *)&CurrVertex1->origin,
  187. (D3DXVECTOR3 *)&CurrVertex2->origin,
  188. (D3DXVECTOR3 *)&CurrVertex3->origin,
  189. (D3DXVECTOR3 *)&ray.m_origin,
  190. (D3DXVECTOR3 *)&ray.m_direction,
  191. &u, &v, &depth) && (depth < curr_depth))
  192. {
  193. Vector u_scalar = (CurrVertex2->origin - CurrVertex1->origin);
  194. Vector v_scalar = (CurrVertex3->origin - CurrVertex1->origin);
  195. Vector face_point = CurrVertex1->origin + (u_scalar * u) + (v_scalar * v);
  196. float vdist1 = (face_point - CurrVertex1->origin).magnitude();
  197. float vdist2 = (face_point - CurrVertex2->origin).magnitude();
  198. float vdist3 = (face_point - CurrVertex3->origin).magnitude();
  199. if (vdist1 <= vdist2)
  200. result = ((vdist1 <= vdist3) ? CurrVertex1 : CurrVertex3);
  201. else
  202. result = ((vdist2 <= vdist3) ? CurrVertex2 : CurrVertex3);
  203. }
  204. }
  205. return result;
  206. }