PhysicsDebug.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. #ifndef STOP_DEBUG
  2. #include "PhysicsScene.h"
  3. #include "PhysicsService.h"
  4. #include "..\Common_h\Render.h"
  5. #include "..\Common_h\Mission.h"
  6. // Moller-Trumbore: ray intersect with triangle(only hit check)
  7. bool IntersectTriangle(const Vector & r0, const Vector & dir, const Vector & v0, const Vector & v1, const Vector & v2, Vector & vRes)
  8. {
  9. Vector edge1, edge2, tvec, pvec, qvec;
  10. float det, inv_det;
  11. /* find vectors for two edges sharing vert0 */
  12. edge1 = v1 - v0;
  13. edge2 = v2 - v0;
  14. /* begin calculating determinant - also used to calculate U parameter */
  15. pvec = dir ^ edge2;
  16. /* if determinant is near zero, ray lies in plane of triangle */
  17. det = edge1 | pvec;
  18. if (det > -0.000001 && det < 0.000001) return false;
  19. inv_det = 1.0f / det;
  20. /* calculate distance from vert0 to ray origin */
  21. tvec = r0 - v0;
  22. Vector n = edge1 ^ edge2;
  23. float a = -(n | tvec);
  24. float b = (n | dir);
  25. if (fabs(b) < 0.000001) return false;
  26. float r = a / b;
  27. if (r < 0.0) return false;
  28. vRes = r0 + r * dir; // intersect point of ray and plane
  29. float u, v, t;
  30. /* calculate U parameter and test bounds */
  31. u = (tvec | pvec) * inv_det;
  32. if (u < 0.0 || u > 1.0) return false;
  33. /* prepare to test V parameter */
  34. qvec = tvec ^ edge1;
  35. /* calculate V parameter and test bounds */
  36. v = (dir | qvec) * inv_det;
  37. if (v < 0.0 || u + v > 1.0) return false;
  38. /* calculate t, ray intersects triangle */
  39. t = (edge2 | qvec) * inv_det;
  40. return true;
  41. }
  42. #ifndef STOP_DEBUG
  43. void PhysicsScene::Debug_DrawMaterialsPatches()
  44. {
  45. long iMaterialShow = m_service->m_gMaterialIndex;
  46. array<Vector> aTrgs(_FL_, 8192);
  47. array<PhysTriangleMaterialID> aMats(_FL_, 32);
  48. OverlapSphere(0.0, 10000.0f, 0xFFFFFFFF, true, true, aTrgs, &aMats);
  49. IRender * render = (IRender *)api->GetService("DX9Render");
  50. IVariable * pVColor = render->GetTechniqueGlobalVariable("Phys_v4Color", _FL_);
  51. Matrix mView = render->GetView();
  52. Matrix mIView = Matrix(mView).Inverse();
  53. Vector vCamPos = mView.GetCamPos();
  54. Vector r0 = vCamPos;
  55. Vector r1 = vCamPos + mIView.MulNormal(Vector(0.0f, 0.0f, 1000.0f));
  56. struct temp_t
  57. {
  58. temp_t() : aTrgs(_FL_, 8192)
  59. {
  60. bInited = false;
  61. dwColor = 0xFFFFFFFF;
  62. };
  63. array<Vector> aTrgs;
  64. dword dwColor;
  65. string sType;
  66. bool bInited;
  67. };
  68. array<temp_t> aTemp(_FL_, 32);
  69. dword dwIntersectMat = -1, dwIntersectTri = -1;
  70. float fMinDistance = 1e+10f;
  71. #define MAX_MATERIALS 64
  72. aTemp.Empty();
  73. for (long j=0; j<=MAX_MATERIALS; j++) aTemp.Add();
  74. for (long i=0; i<aTrgs.Len() / 3; i++)
  75. {
  76. long mat = aMats[i];
  77. if (mat > MAX_MATERIALS) continue; // Мелкий хак, все равно если материалов больше 64 - значит кто-то зажрался!
  78. temp_t & t = aTemp[mat];
  79. if (!t.bInited)
  80. {
  81. t.bInited = true;
  82. t.dwColor = ARGB(255, 25, 25, 25);
  83. t.sType = "Unknown: " + mat;
  84. switch ((PhysTriangleMaterialID)mat)
  85. {
  86. case pmtlid_air: t.dwColor = ARGB(255, 0, 210, 255); t.sType = "Air"; break;
  87. case pmtlid_ground: t.dwColor = ARGB(255, 110, 148, 92); t.sType = "Ground"; break;
  88. case pmtlid_stone: t.dwColor = ARGB(255, 206, 206, 206); t.sType = "Stone"; break;
  89. case pmtlid_sand: t.dwColor = ARGB(255, 237, 255, 211); t.sType = "Sand"; break;
  90. case pmtlid_wood: t.dwColor = ARGB(255, 184, 140, 87); t.sType = "Wood"; break;
  91. case pmtlid_grass: t.dwColor = ARGB(255, 47, 214, 55); t.sType = "Grass"; break;
  92. case pmtlid_water: t.dwColor = ARGB(255, 0, 180, 255); t.sType = "Water"; break;
  93. case pmtlid_iron: t.dwColor = ARGB(255, 200, 200, 200); t.sType = "Iron"; break;
  94. case pmtlid_fabrics: t.dwColor = ARGB(255, 228, 228, 228); t.sType = "Fabrics"; break;
  95. case pmtlid_other1: t.dwColor = ARGB(255, 80, 80, 80); t.sType = "Other1"; break;
  96. case pmtlid_other2: t.dwColor = ARGB(255, 80, 80, 80); t.sType = "Other2"; break;
  97. case pmtlid_other3: t.dwColor = ARGB(255, 80, 80, 80); t.sType = "Other3"; break;
  98. case pmtlid_other4: t.dwColor = ARGB(255, 80, 80, 80); t.sType = "Other4"; break;
  99. }
  100. }
  101. t.aTrgs.Add(aTrgs[i * 3 + 0]);
  102. t.aTrgs.Add(aTrgs[i * 3 + 1]);
  103. t.aTrgs.Add(aTrgs[i * 3 + 2]);
  104. Vector vRes;
  105. /*if (IntersectTriangle(r0, (r1 - r0), aTrgs[i * 3 + 0], aTrgs[i * 3 + 1], aTrgs[i * 3 + 2], vRes))
  106. {
  107. float fDistance = ~(vRes - vCamPos);
  108. if (fDistance < fMinDistance)
  109. {
  110. fMinDistance = fDistance;
  111. dwIntersectMat = mat;
  112. dwIntersectTri = t.aTrgs.Last();
  113. }
  114. }*/
  115. }
  116. if (iMaterialShow >= 0 && iMaterialShow > (long)aTemp.Last()) iMaterialShow = (long)aTemp.Last();
  117. render->SetWorld(Matrix());
  118. render->FlushBufferedLines();
  119. for (long i=0, k=0; i<aTemp.Len(); i++)
  120. {
  121. temp_t & t = aTemp[i];
  122. if (t.aTrgs.IsEmpty()) continue;
  123. if (iMaterialShow >= 0 && iMaterialShow != k)
  124. {
  125. k++;
  126. continue;
  127. }
  128. dword dwColor = t.dwColor;
  129. Color c(dwColor);
  130. // рисуем треугольники
  131. pVColor->SetVector4((c * 0.8f).v4);
  132. ShaderId id;
  133. render->GetShaderId("dbgPhysPolygons", id);
  134. render->DrawPrimitiveUP(id, PT_TRIANGLELIST, t.aTrgs.Size() / 3, t.aTrgs.GetBuffer(), sizeof(Vector));
  135. // добавляем линии сверху
  136. for (long j=0; j<t.aTrgs.Len() / 3; j++)
  137. {
  138. render->DrawBufferedLine(t.aTrgs[j * 3 + 0], dwColor, t.aTrgs[j * 3 + 1], dwColor, false, "dbgPhysLine");
  139. render->DrawBufferedLine(t.aTrgs[j * 3 + 1], dwColor, t.aTrgs[j * 3 + 2], dwColor, false, "dbgPhysLine");
  140. render->DrawBufferedLine(t.aTrgs[j * 3 + 2], dwColor, t.aTrgs[j * 3 + 0], dwColor, false, "dbgPhysLine");
  141. }
  142. k++;
  143. }
  144. render->FlushBufferedLines(true, "dbgPhysLine");
  145. render->Print(20.0f, 30.0f, 0xFFFFFFFF, "Current material: %s", (dwIntersectMat != -1 && dwIntersectTri != -1) ? aTemp[dwIntersectMat].sType.c_str() : "None");
  146. //render->Print(20.0f, 50.0f, 0xFFFFFFFF, "Use '+' and '-' keys to select single material");
  147. render->Print(20.0f, 75.0f, 0xFFFFFFFF, "Materials found:");
  148. for (long i=0, k=0; i<aTemp.Len(); i++)
  149. {
  150. temp_t & t = aTemp[i];
  151. if (t.aTrgs.IsEmpty()) continue;
  152. dword dwColor = 0xFFFFFFFF;
  153. if (iMaterialShow >= 0 && iMaterialShow != k) dwColor = 0xFF6F6F6F;
  154. render->Print(38.0f, 95.0f + k * 20.0f, dwColor, "%d. %s : %d triangles.", k, t.sType.c_str(), t.aTrgs.Size() / 3);
  155. dwColor = t.dwColor;
  156. RS_SPRITE spr[4];
  157. float dx = 1024.0f;
  158. float dy = 768.0f;
  159. float x1 = (2.0f * 23.0f / dx) - 1.0f;
  160. float x2 = (2.0f * 35.0f / dx) - 1.0f;
  161. float y1 = 1.0f - (2.0f * (98.0f + k * 20.0f) / dy);
  162. float y2 = 1.0f - (2.0f * (12.0f + 98.0f + k * 20.0f) / dy);
  163. spr[0].vPos = Vector (x1, y1, 0.0f);
  164. spr[1].vPos = Vector (x2, y1, 0.0f);
  165. spr[2].vPos = Vector (x2, y2, 0.0f);
  166. spr[3].vPos = Vector (x1, y2, 0.0f);
  167. spr[0].tu = 0.0f; spr[0].tv = 0.0f;
  168. spr[1].tu = 1.0f; spr[1].tv = 0.0f;
  169. spr[2].tu = 1.0f; spr[2].tv = 1.0f;
  170. spr[3].tu = 0.0f; spr[3].tv = 1.0f;
  171. spr[0].dwColor = dwColor;
  172. spr[1].dwColor = dwColor;
  173. spr[2].dwColor = dwColor;
  174. spr[3].dwColor = dwColor;
  175. render->DrawSprites(null, &spr[0], 1);
  176. k++;
  177. }
  178. RS_RECT r;
  179. r.dwColor = 0xFFFFFFFF;
  180. r.dwSubTexture = 0;
  181. r.fAngle = 0.0f;
  182. r.fSizeX = 0.0005f; r.fSizeY = 0.0005f;
  183. r.vPos = mIView.MulVertex(Vector(0.0f, 0.0f, 0.2f));
  184. render->SetWorld(Matrix());
  185. render->DrawRects(null, &r, 1);
  186. if (dwIntersectMat != -1 && dwIntersectTri != -1)
  187. render->Print(mIView.MulVertex(Vector(0.0f, 0.0f, 7.0f)), 10.0f, -0.9f, 0xFFFFFFFF, aTemp[dwIntersectMat].sType.c_str());
  188. pVColor = NULL;
  189. }
  190. void PhysicsScene::DebugFrame()
  191. {
  192. IRender * render = (IRender *)api->GetService("DX9Render");
  193. for (int i=0; i<m_spheres.Len(); i++)
  194. render->DrawSphere(m_spheres[i], 0.2f, 0xFF00FF00);
  195. if (api->DebugKeyState('I'))
  196. m_spheres.Empty();
  197. if (m_service->m_gShowColliders)
  198. Debug_DrawMaterialsPatches();
  199. if (m_service->m_gShowPhysBoxes)
  200. {
  201. array<Object*> objs(_FL_);
  202. api->FindObject("CameraController", objs);
  203. for (long i=0; i<objs.Len(); i++)
  204. {
  205. MissionObject * camCon = (MissionObject *)objs[i];
  206. dword numPhysObjs = camCon->QTFindObjects(MG_AI_COLLISION, -Vector(10000.0f), Vector(10000.0f));
  207. for (dword j=0; j<numPhysObjs; j++)
  208. {
  209. IMissionQTObject * fo = camCon->QTGetObject(j);
  210. if (!fo) continue;
  211. const Vector & boxCenter = fo->GetBoxCenter();
  212. Vector boxSize05 = fo->GetBoxSize()*0.5f;
  213. Matrix mtx(fo->GetMatrix());
  214. mtx.pos = mtx*boxCenter;
  215. render->DrawBox(-boxSize05, boxSize05, mtx);
  216. }
  217. }
  218. }
  219. if (m_service->m_gShowWorldPoint)
  220. {
  221. static float coeff = 0.0f;
  222. const Vector & pos = m_service->m_gWorldPoint;
  223. render->DrawSphere(pos, 0.1f);
  224. float fDeltaTime = api->GetDeltaTime();
  225. coeff += fDeltaTime;
  226. coeff -= 2.0f * long(coeff / 2.0f);
  227. float dist0 = 0.2f + ((coeff < 1.0f) ? coeff : 2.0f - coeff);
  228. float dist1 = dist0 + 2.5f;
  229. render->DrawVector(pos + Vector(0.0f, dist1, 0.0f), pos + Vector(0.0f, dist0, 0.0f), 0xFF00FF00);
  230. render->DrawVector(pos + Vector(0.0f, -dist1, 0.0f), pos + Vector(0.0f, -dist0, 0.0f), 0xFF00FF00);
  231. render->DrawVector(pos + Vector(dist1, 0.0f, 0.0f), pos + Vector(dist0, 0.0f, 0.0f), 0xFF00FF00);
  232. render->DrawVector(pos + Vector(-dist1, 0.0f, 0.0f), pos + Vector(-dist0, 0.0f, 0.0f), 0xFF00FF00);
  233. render->DrawVector(pos + Vector(0.0f, 0.0f, dist1), pos + Vector(0.0f, 0.0f, dist0), 0xFF00FF00);
  234. render->DrawVector(pos + Vector(0.0f, 0.0f, -dist1), pos + Vector(0.0f, 0.0f, -dist0), 0xFF00FF00);
  235. }
  236. }
  237. #endif
  238. #endif