Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

664 lines
24 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Utility functions for using debug overlays to visualize information
  4. // in the world. Uses the IVDebugOverlay interface.
  5. //
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "debugoverlay_shared.h"
  9. #include "mathlib/mathlib.h"
  10. // memdbgon must be the last include file in a .cpp file!!!
  11. #include "tier0/memdbgon.h"
  12. #define MAX_OVERLAY_DIST_SQR 90000000
  13. //-----------------------------------------------------------------------------
  14. // Purpose: Local player on the server or client
  15. //-----------------------------------------------------------------------------
  16. CBasePlayer *GetLocalPlayer( void )
  17. {
  18. #if defined( CLIENT_DLL)
  19. return C_BasePlayer::GetLocalPlayer();
  20. #else
  21. return UTIL_GetListenServerHost();
  22. #endif
  23. }
  24. //-----------------------------------------------------------------------------
  25. // Purpose: Debug player by index
  26. //-----------------------------------------------------------------------------
  27. CBasePlayer *GetDebugPlayer( void )
  28. {
  29. #if defined( CLIENT_DLL )
  30. //NOTENOTE: This doesn't necessarily make sense on the client
  31. return GetLocalPlayer();
  32. #else
  33. return UTIL_PlayerByIndex(CBaseEntity::m_nDebugPlayer);
  34. #endif
  35. }
  36. //-----------------------------------------------------------------------------
  37. // Purpose: Draw a box with no orientation
  38. //-----------------------------------------------------------------------------
  39. void NDebugOverlay::Box(const Vector &origin, const Vector &mins, const Vector &maxs, int r, int g, int b, int a, float flDuration)
  40. {
  41. BoxAngles( origin, mins, maxs, vec3_angle, r, g, b, a, flDuration );
  42. }
  43. //-----------------------------------------------------------------------------
  44. // Purpose: Draw box oriented to a Vector direction
  45. //-----------------------------------------------------------------------------
  46. void NDebugOverlay::BoxDirection(const Vector &origin, const Vector &mins, const Vector &maxs, const Vector &orientation, int r, int g, int b, int a, float duration)
  47. {
  48. // convert forward vector to angles
  49. QAngle f_angles = vec3_angle;
  50. f_angles.y = UTIL_VecToYaw( orientation );
  51. BoxAngles( origin, mins, maxs, f_angles, r, g, b, a, duration );
  52. }
  53. //-----------------------------------------------------------------------------
  54. // Purpose: Draw box oriented to a QAngle direction
  55. //-----------------------------------------------------------------------------
  56. void NDebugOverlay::BoxAngles(const Vector &origin, const Vector &mins, const Vector &maxs, const QAngle &angles, int r, int g, int b, int a, float duration)
  57. {
  58. if ( debugoverlay )
  59. {
  60. debugoverlay->AddBoxOverlay( origin, mins, maxs, angles, r, g, b, a, duration );
  61. }
  62. }
  63. //-----------------------------------------------------------------------------
  64. // Purpose: Draws a swept box
  65. //-----------------------------------------------------------------------------
  66. void NDebugOverlay::SweptBox( const Vector& start, const Vector& end, const Vector& mins, const Vector& maxs, const QAngle & angles, int r, int g, int b, int a, float flDuration)
  67. {
  68. if ( debugoverlay )
  69. {
  70. debugoverlay->AddSweptBoxOverlay( start, end, mins, maxs, angles, r, g, b, a, flDuration );
  71. }
  72. }
  73. //-----------------------------------------------------------------------------
  74. // Purpose: Draws a box around an entity
  75. //-----------------------------------------------------------------------------
  76. void NDebugOverlay::EntityBounds( const CBaseEntity *pEntity, int r, int g, int b, int a, float flDuration )
  77. {
  78. const CCollisionProperty *pCollide = pEntity->CollisionProp();
  79. BoxAngles( pCollide->GetCollisionOrigin(), pCollide->OBBMins(), pCollide->OBBMaxs(), pCollide->GetCollisionAngles(), r, g, b, a, flDuration );
  80. }
  81. //-----------------------------------------------------------------------------
  82. // Purpose: Draws a line from one position to another
  83. //-----------------------------------------------------------------------------
  84. void NDebugOverlay::Line( const Vector &origin, const Vector &target, int r, int g, int b, bool noDepthTest, float duration )
  85. {
  86. // --------------------------------------------------------------
  87. // Clip the line before sending so we
  88. // don't overflow the client message buffer
  89. // --------------------------------------------------------------
  90. CBasePlayer *player = GetLocalPlayer();
  91. if ( player == NULL )
  92. return;
  93. // Clip line that is far away
  94. if (((player->GetAbsOrigin() - origin).LengthSqr() > MAX_OVERLAY_DIST_SQR) &&
  95. ((player->GetAbsOrigin() - target).LengthSqr() > MAX_OVERLAY_DIST_SQR) )
  96. return;
  97. // Clip line that is behind the client
  98. Vector clientForward;
  99. player->EyeVectors( &clientForward );
  100. Vector toOrigin = origin - player->GetAbsOrigin();
  101. Vector toTarget = target - player->GetAbsOrigin();
  102. float dotOrigin = DotProduct(clientForward,toOrigin);
  103. float dotTarget = DotProduct(clientForward,toTarget);
  104. if (dotOrigin < 0 && dotTarget < 0)
  105. return;
  106. if ( debugoverlay )
  107. {
  108. debugoverlay->AddLineOverlay( origin, target, r, g, b, noDepthTest, duration );
  109. }
  110. }
  111. //-----------------------------------------------------------------------------
  112. // Purpose: Draw triangle
  113. //-----------------------------------------------------------------------------
  114. void NDebugOverlay::Triangle( const Vector &p1, const Vector &p2, const Vector &p3, int r, int g, int b, int a, bool noDepthTest, float duration )
  115. {
  116. CBasePlayer *player = GetLocalPlayer();
  117. if ( !player )
  118. return;
  119. // Clip triangles that are far away
  120. Vector to1 = p1 - player->GetAbsOrigin();
  121. Vector to2 = p2 - player->GetAbsOrigin();
  122. Vector to3 = p3 - player->GetAbsOrigin();
  123. if ((to1.LengthSqr() > MAX_OVERLAY_DIST_SQR) &&
  124. (to2.LengthSqr() > MAX_OVERLAY_DIST_SQR) &&
  125. (to3.LengthSqr() > MAX_OVERLAY_DIST_SQR))
  126. {
  127. return;
  128. }
  129. // Clip triangles that are behind the client
  130. Vector clientForward;
  131. player->EyeVectors( &clientForward );
  132. float dot1 = DotProduct(clientForward, to1);
  133. float dot2 = DotProduct(clientForward, to2);
  134. float dot3 = DotProduct(clientForward, to3);
  135. if (dot1 < 0 && dot2 < 0 && dot3 < 0)
  136. return;
  137. if ( debugoverlay )
  138. {
  139. debugoverlay->AddTriangleOverlay( p1, p2, p3, r, g, b, a, noDepthTest, duration );
  140. }
  141. }
  142. //-----------------------------------------------------------------------------
  143. // Purpose: Draw entity text overlay
  144. //-----------------------------------------------------------------------------
  145. void NDebugOverlay::EntityText( int entityID, int text_offset, const char *text, float duration, int r, int g, int b, int a )
  146. {
  147. if ( debugoverlay )
  148. {
  149. debugoverlay->AddEntityTextOverlay( entityID, text_offset, duration,
  150. (int)clamp(r * 255.f,0.f,255.f), (int)clamp(g * 255.f,0.f,255.f), (int)clamp(b * 255.f,0.f,255.f),
  151. (int)clamp(a * 255.f,0.f,255.f), text );
  152. }
  153. }
  154. //-----------------------------------------------------------------------------
  155. // Purpose: Draw entity text overlay at a specific position
  156. //-----------------------------------------------------------------------------
  157. void NDebugOverlay::EntityTextAtPosition( const Vector &origin, int text_offset, const char *text, float duration, int r, int g, int b, int a )
  158. {
  159. if ( debugoverlay )
  160. {
  161. debugoverlay->AddTextOverlayRGB( origin, text_offset, duration, r, g, b, a, "%s", text );
  162. }
  163. }
  164. //-----------------------------------------------------------------------------
  165. // Purpose: Add grid overlay
  166. //-----------------------------------------------------------------------------
  167. void NDebugOverlay::Grid( const Vector &vPosition )
  168. {
  169. if ( debugoverlay )
  170. {
  171. debugoverlay->AddGridOverlay( vPosition );
  172. }
  173. }
  174. //-----------------------------------------------------------------------------
  175. // Purpose: Draw debug text at a position
  176. //-----------------------------------------------------------------------------
  177. void NDebugOverlay::Text( const Vector &origin, const char *text, bool bViewCheck, float duration )
  178. {
  179. CBasePlayer *player = GetLocalPlayer();
  180. if ( !player )
  181. return;
  182. // Clip text that is far away
  183. if ( ( player->GetAbsOrigin() - origin ).LengthSqr() > MAX_OVERLAY_DIST_SQR )
  184. return;
  185. // Clip text that is behind the client
  186. Vector clientForward;
  187. player->EyeVectors( &clientForward );
  188. Vector toText = origin - player->GetAbsOrigin();
  189. float dotPr = DotProduct(clientForward,toText);
  190. if (dotPr < 0)
  191. return;
  192. // Clip text that is obscured
  193. if (bViewCheck)
  194. {
  195. trace_t tr;
  196. UTIL_TraceLine(player->GetAbsOrigin(), origin, MASK_OPAQUE, NULL, COLLISION_GROUP_NONE, &tr);
  197. if ((tr.endpos - origin).Length() > 10)
  198. return;
  199. }
  200. if ( debugoverlay )
  201. {
  202. debugoverlay->AddTextOverlay( origin, duration, "%s", text );
  203. }
  204. }
  205. //-----------------------------------------------------------------------------
  206. // Purpose: Add debug overlay text with screen position
  207. //-----------------------------------------------------------------------------
  208. void NDebugOverlay::ScreenText( float flXpos, float flYpos, const char *text, int r, int g, int b, int a, float duration )
  209. {
  210. if ( debugoverlay )
  211. {
  212. debugoverlay->AddScreenTextOverlay( flXpos, flYpos, duration, r, g, b, a, text );
  213. }
  214. }
  215. //-----------------------------------------------------------------------------
  216. // Purpose: Draw a colored 3D cross of the given hull size at the given position
  217. //-----------------------------------------------------------------------------
  218. void NDebugOverlay::Cross3D(const Vector &position, const Vector &mins, const Vector &maxs, int r, int g, int b, bool noDepthTest, float fDuration )
  219. {
  220. Vector start = mins + position;
  221. Vector end = maxs + position;
  222. Line(start,end, r, g, b, noDepthTest,fDuration);
  223. start.x += (maxs.x - mins.x);
  224. end.x -= (maxs.x - mins.x);
  225. Line(start,end, r, g, b, noDepthTest,fDuration);
  226. start.y += (maxs.y - mins.y);
  227. end.y -= (maxs.y - mins.y);
  228. Line(start,end, r, g, b, noDepthTest,fDuration);
  229. start.x -= (maxs.x - mins.x);
  230. end.x += (maxs.x - mins.x);
  231. Line(start,end, r, g, b, noDepthTest,fDuration);
  232. }
  233. //-----------------------------------------------------------------------------
  234. // Purpose: Draw a colored 3D cross of the given size at the given position
  235. //-----------------------------------------------------------------------------
  236. void NDebugOverlay::Cross3D(const Vector &position, float size, int r, int g, int b, bool noDepthTest, float flDuration )
  237. {
  238. Line( position + Vector(size,0,0), position - Vector(size,0,0), r, g, b, noDepthTest, flDuration );
  239. Line( position + Vector(0,size,0), position - Vector(0,size,0), r, g, b, noDepthTest, flDuration );
  240. Line( position + Vector(0,0,size), position - Vector(0,0,size), r, g, b, noDepthTest, flDuration );
  241. }
  242. //-----------------------------------------------------------------------------
  243. // Purpose: Draw an oriented, colored 3D cross of the given size at the given position (via a vector)
  244. //-----------------------------------------------------------------------------
  245. void NDebugOverlay::Cross3DOriented( const Vector &position, const QAngle &angles, float size, int r, int g, int b, bool noDepthTest, float flDuration )
  246. {
  247. Vector forward, right, up;
  248. AngleVectors( angles, &forward, &right, &up );
  249. forward *= size;
  250. right *= size;
  251. up *= size;
  252. Line( position + right, position - right, r, g, b, noDepthTest, flDuration );
  253. Line( position + forward, position - forward, r, g, b, noDepthTest, flDuration );
  254. Line( position + up, position - up, r, g, b, noDepthTest, flDuration );
  255. }
  256. //-----------------------------------------------------------------------------
  257. // Purpose: Draw an oriented, colored 3D cross of the given size at the given position (via a matrix)
  258. //-----------------------------------------------------------------------------
  259. void NDebugOverlay::Cross3DOriented( const matrix3x4_t &m, float size, int c, bool noDepthTest, float flDuration )
  260. {
  261. Vector forward, left, up, position;
  262. MatrixGetColumn( m, 0, forward );
  263. MatrixGetColumn( m, 1, left );
  264. MatrixGetColumn( m, 2, up );
  265. MatrixGetColumn( m, 3, position );
  266. forward *= size;
  267. left *= size;
  268. up *= size;
  269. Line( position + left, position - left, 0, c, 0, noDepthTest, flDuration );
  270. Line( position + forward, position - forward, c, 0, 0, noDepthTest, flDuration );
  271. Line( position + up, position - up, 0, 0, c, noDepthTest, flDuration );
  272. }
  273. //--------------------------------------------------------------------------------
  274. // Purpose : Draw tick marks between start and end position of the given distance
  275. // with text every tickTextDist steps apart.
  276. //--------------------------------------------------------------------------------
  277. void NDebugOverlay::DrawTickMarkedLine(const Vector &startPos, const Vector &endPos, float tickDist, int tickTextDist, int r, int g, int b, bool noDepthTest, float duration )
  278. {
  279. CBasePlayer* pPlayer = GetDebugPlayer();
  280. if ( !pPlayer )
  281. return;
  282. Vector lineDir = (endPos - startPos);
  283. float lineDist = VectorNormalize( lineDir );
  284. int numTicks = lineDist/tickDist;
  285. Vector vBodyDir;
  286. #if defined( CLIENT_DLL )
  287. AngleVectors( pPlayer->LocalEyeAngles(), &vBodyDir );
  288. #else
  289. vBodyDir = pPlayer->BodyDirection2D( );
  290. #endif
  291. Vector upVec = 4*vBodyDir;
  292. Vector sideDir;
  293. Vector tickPos = startPos;
  294. int tickTextCnt = 0;
  295. CrossProduct(lineDir, upVec, sideDir);
  296. // First draw the line
  297. Line(startPos, endPos, r,g,b,noDepthTest,duration);
  298. // Now draw the ticks
  299. for (int i=0;i<numTicks+1;i++)
  300. {
  301. // Draw tick mark
  302. Vector tickLeft = tickPos - sideDir;
  303. Vector tickRight = tickPos + sideDir;
  304. // Draw tick mark text
  305. if (tickTextCnt == tickTextDist)
  306. {
  307. char text[25];
  308. Q_snprintf(text,sizeof(text),"%i",i);
  309. Vector textPos = tickLeft + Vector(0,0,8);
  310. Line(tickLeft, tickRight, 255,255,255,noDepthTest,duration);
  311. Text( textPos, text, true, 0 );
  312. tickTextCnt = 0;
  313. }
  314. else
  315. {
  316. Line(tickLeft, tickRight, r,g,b,noDepthTest,duration);
  317. }
  318. tickTextCnt++;
  319. tickPos = tickPos + (tickDist * lineDir);
  320. }
  321. }
  322. //------------------------------------------------------------------------------
  323. // Purpose : Draw crosshair on ground where player is looking
  324. //------------------------------------------------------------------------------
  325. void NDebugOverlay::DrawGroundCrossHairOverlay( void )
  326. {
  327. CBasePlayer* pPlayer = GetDebugPlayer();
  328. if ( !pPlayer )
  329. return;
  330. // Trace a line to where player is looking
  331. Vector vForward;
  332. Vector vSource = pPlayer->EyePosition();
  333. pPlayer->EyeVectors( &vForward );
  334. trace_t tr;
  335. UTIL_TraceLine ( vSource, vSource + vForward * 2048, MASK_SOLID, pPlayer, COLLISION_GROUP_NONE, &tr);
  336. float dotPr = DotProduct(Vector(0,0,1),tr.plane.normal);
  337. if (tr.fraction != 1.0 && dotPr > 0.5)
  338. {
  339. tr.endpos.z += 1;
  340. float scale = 6;
  341. Vector startPos = tr.endpos + Vector (-scale,0,0);
  342. Vector endPos = tr.endpos + Vector ( scale,0,0);
  343. Line(startPos, endPos, 255, 0, 0,false,0);
  344. startPos = tr.endpos + Vector (0,-scale,0);
  345. endPos = tr.endpos + Vector (0, scale,0);
  346. Line(startPos, endPos, 255, 0, 0,false,0);
  347. }
  348. }
  349. //--------------------------------------------------------------------------------
  350. // Purpose : Draw a horizontal arrow pointing in the specified direction
  351. //--------------------------------------------------------------------------------
  352. void NDebugOverlay::HorzArrow( const Vector &startPos, const Vector &endPos, float width, int r, int g, int b, int a, bool noDepthTest, float flDuration)
  353. {
  354. Vector lineDir = (endPos - startPos);
  355. VectorNormalize( lineDir );
  356. Vector upVec = Vector( 0, 0, 1 );
  357. Vector sideDir;
  358. float radius = width / 2.0;
  359. CrossProduct(lineDir, upVec, sideDir);
  360. Vector p1 = startPos - sideDir * radius;
  361. Vector p2 = endPos - lineDir * width - sideDir * radius;
  362. Vector p3 = endPos - lineDir * width - sideDir * width;
  363. Vector p4 = endPos;
  364. Vector p5 = endPos - lineDir * width + sideDir * width;
  365. Vector p6 = endPos - lineDir * width + sideDir * radius;
  366. Vector p7 = startPos + sideDir * radius;
  367. // Outline the arrow
  368. Line(p1, p2, r,g,b,noDepthTest,flDuration);
  369. Line(p2, p3, r,g,b,noDepthTest,flDuration);
  370. Line(p3, p4, r,g,b,noDepthTest,flDuration);
  371. Line(p4, p5, r,g,b,noDepthTest,flDuration);
  372. Line(p5, p6, r,g,b,noDepthTest,flDuration);
  373. Line(p6, p7, r,g,b,noDepthTest,flDuration);
  374. if ( a > 0 )
  375. {
  376. // Fill us in with triangles
  377. Triangle( p5, p4, p3, r, g, b, a, noDepthTest, flDuration ); // Tip
  378. Triangle( p1, p7, p6, r, g, b, a, noDepthTest, flDuration ); // Shaft
  379. Triangle( p6, p2, p1, r, g, b, a, noDepthTest, flDuration );
  380. // And backfaces
  381. Triangle( p3, p4, p5, r, g, b, a, noDepthTest, flDuration ); // Tip
  382. Triangle( p6, p7, p1, r, g, b, a, noDepthTest, flDuration ); // Shaft
  383. Triangle( p1, p2, p6, r, g, b, a, noDepthTest, flDuration );
  384. }
  385. }
  386. //-----------------------------------------------------------------------------
  387. // Purpose : Draw a horizontal arrow pointing in the specified direction by yaw value
  388. //-----------------------------------------------------------------------------
  389. void NDebugOverlay::YawArrow( const Vector &startPos, float yaw, float length, float width, int r, int g, int b, int a, bool noDepthTest, float flDuration)
  390. {
  391. Vector forward = UTIL_YawToVector( yaw );
  392. HorzArrow( startPos, startPos + forward * length, width, r, g, b, a, noDepthTest, flDuration );
  393. }
  394. //--------------------------------------------------------------------------------
  395. // Purpose : Draw a vertical arrow at a position
  396. //--------------------------------------------------------------------------------
  397. void NDebugOverlay::VertArrow( const Vector &startPos, const Vector &endPos, float width, int r, int g, int b, int a, bool noDepthTest, float flDuration)
  398. {
  399. Vector lineDir = (endPos - startPos);
  400. VectorNormalize( lineDir );
  401. Vector upVec;
  402. Vector sideDir;
  403. float radius = width / 2.0;
  404. VectorVectors( lineDir, sideDir, upVec );
  405. Vector p1 = startPos - upVec * radius;
  406. Vector p2 = endPos - lineDir * width - upVec * radius;
  407. Vector p3 = endPos - lineDir * width - upVec * width;
  408. Vector p4 = endPos;
  409. Vector p5 = endPos - lineDir * width + upVec * width;
  410. Vector p6 = endPos - lineDir * width + upVec * radius;
  411. Vector p7 = startPos + upVec * radius;
  412. // Outline the arrow
  413. Line(p1, p2, r,g,b,noDepthTest,flDuration);
  414. Line(p2, p3, r,g,b,noDepthTest,flDuration);
  415. Line(p3, p4, r,g,b,noDepthTest,flDuration);
  416. Line(p4, p5, r,g,b,noDepthTest,flDuration);
  417. Line(p5, p6, r,g,b,noDepthTest,flDuration);
  418. Line(p6, p7, r,g,b,noDepthTest,flDuration);
  419. if ( a > 0 )
  420. {
  421. // Fill us in with triangles
  422. Triangle( p5, p4, p3, r, g, b, a, noDepthTest, flDuration ); // Tip
  423. Triangle( p1, p7, p6, r, g, b, a, noDepthTest, flDuration ); // Shaft
  424. Triangle( p6, p2, p1, r, g, b, a, noDepthTest, flDuration );
  425. // And backfaces
  426. Triangle( p3, p4, p5, r, g, b, a, noDepthTest, flDuration ); // Tip
  427. Triangle( p6, p7, p1, r, g, b, a, noDepthTest, flDuration ); // Shaft
  428. Triangle( p1, p2, p6, r, g, b, a, noDepthTest, flDuration );
  429. }
  430. }
  431. //-----------------------------------------------------------------------------
  432. // Purpose: Draw an axis
  433. //-----------------------------------------------------------------------------
  434. void NDebugOverlay::Axis( const Vector &position, const QAngle &angles, float size, bool noDepthTest, float flDuration )
  435. {
  436. Vector xvec, yvec, zvec;
  437. AngleVectors( angles, &xvec, &yvec, &zvec );
  438. xvec = position + (size * xvec);
  439. yvec = position - (size * yvec); // Left is positive
  440. zvec = position + (size * zvec);
  441. Line( position, xvec, 255, 0, 0, noDepthTest, flDuration );
  442. Line( position, yvec, 0, 255, 0, noDepthTest, flDuration );
  443. Line( position, zvec, 0, 0, 255, noDepthTest, flDuration );
  444. }
  445. //-----------------------------------------------------------------------------
  446. // Purpose: Draw circles to suggest a sphere
  447. //-----------------------------------------------------------------------------
  448. void NDebugOverlay::Sphere( const Vector &center, float radius, int r, int g, int b, bool noDepthTest, float flDuration )
  449. {
  450. Vector edge, lastEdge;
  451. float axisSize = radius;
  452. Line( center + Vector( 0, 0, -axisSize ), center + Vector( 0, 0, axisSize ), r, g, b, noDepthTest, flDuration );
  453. Line( center + Vector( 0, -axisSize, 0 ), center + Vector( 0, axisSize, 0 ), r, g, b, noDepthTest, flDuration );
  454. Line( center + Vector( -axisSize, 0, 0 ), center + Vector( axisSize, 0, 0 ), r, g, b, noDepthTest, flDuration );
  455. lastEdge = Vector( radius + center.x, center.y, center.z );
  456. float angle;
  457. for( angle=0.0f; angle <= 360.0f; angle += 22.5f )
  458. {
  459. edge.x = radius * cosf( angle / 180.0f * M_PI ) + center.x;
  460. edge.y = center.y;
  461. edge.z = radius * sinf( angle / 180.0f * M_PI ) + center.z;
  462. Line( edge, lastEdge, r, g, b, noDepthTest, flDuration );
  463. lastEdge = edge;
  464. }
  465. lastEdge = Vector( center.x, radius + center.y, center.z );
  466. for( angle=0.0f; angle <= 360.0f; angle += 22.5f )
  467. {
  468. edge.x = center.x;
  469. edge.y = radius * cosf( angle / 180.0f * M_PI ) + center.y;
  470. edge.z = radius * sinf( angle / 180.0f * M_PI ) + center.z;
  471. Line( edge, lastEdge, r, g, b, noDepthTest, flDuration );
  472. lastEdge = edge;
  473. }
  474. lastEdge = Vector( center.x, radius + center.y, center.z );
  475. for( angle=0.0f; angle <= 360.0f; angle += 22.5f )
  476. {
  477. edge.x = radius * cosf( angle / 180.0f * M_PI ) + center.x;
  478. edge.y = radius * sinf( angle / 180.0f * M_PI ) + center.y;
  479. edge.z = center.z;
  480. Line( edge, lastEdge, r, g, b, noDepthTest, flDuration );
  481. lastEdge = edge;
  482. }
  483. }
  484. //-----------------------------------------------------------------------------
  485. // Purpose: Draw a circle whose center is at a position, facing the camera
  486. //-----------------------------------------------------------------------------
  487. void NDebugOverlay::Circle( const Vector &position, float radius, int r, int g, int b, int a, bool bNoDepthTest, float flDuration )
  488. {
  489. CBasePlayer *player = GetLocalPlayer();
  490. if ( player == NULL )
  491. return;
  492. Vector clientForward;
  493. player->EyeVectors( &clientForward );
  494. QAngle vecAngles;
  495. VectorAngles( clientForward, vecAngles );
  496. Circle( position, vecAngles, radius, r, g, b, a, bNoDepthTest, flDuration );
  497. }
  498. //-----------------------------------------------------------------------------
  499. // Purpose: Draw a circle whose center is at a position and is facing a specified direction
  500. //-----------------------------------------------------------------------------
  501. void NDebugOverlay::Circle( const Vector &position, const QAngle &angles, float radius, int r, int g, int b, int a, bool bNoDepthTest, float flDuration )
  502. {
  503. // Setup our transform matrix
  504. matrix3x4_t xform;
  505. AngleMatrix( angles, position, xform );
  506. Vector xAxis, yAxis;
  507. // default draws circle in the y/z plane
  508. MatrixGetColumn( xform, 2, xAxis );
  509. MatrixGetColumn( xform, 1, yAxis );
  510. Circle( position, xAxis, yAxis, radius, r, g, b, a, bNoDepthTest, flDuration );
  511. }
  512. void NDebugOverlay::Circle( const Vector &position, const Vector &xAxis, const Vector &yAxis, float radius, int r, int g, int b, int a, bool bNoDepthTest, float flDuration )
  513. {
  514. const unsigned int nSegments = 16;
  515. const float flRadStep = (M_PI*2.0f) / (float) nSegments;
  516. Vector vecLastPosition;
  517. // Find our first position
  518. // Retained for triangle fanning
  519. Vector vecStart = position + xAxis * radius;
  520. Vector vecPosition = vecStart;
  521. // Draw out each segment (fanning triangles if we have an alpha amount)
  522. for ( int i = 1; i <= nSegments; i++ )
  523. {
  524. // Store off our last position
  525. vecLastPosition = vecPosition;
  526. // Calculate the new one
  527. float flSin, flCos;
  528. SinCos( flRadStep*i, &flSin, &flCos );
  529. vecPosition = position + (xAxis * flCos * radius) + (yAxis * flSin * radius);
  530. // Draw the line
  531. Line( vecLastPosition, vecPosition, r, g, b, bNoDepthTest, flDuration );
  532. // If we have an alpha value, then draw the fan
  533. if ( a && i > 1 )
  534. {
  535. if ( debugoverlay )
  536. {
  537. debugoverlay->AddTriangleOverlay( vecStart, vecLastPosition, vecPosition, r, g, b, a, bNoDepthTest, flDuration );
  538. }
  539. }
  540. }
  541. }
  542. void NDebugOverlay::Sphere( const Vector &position, const QAngle &angles, float radius, int r, int g, int b, int a, bool bNoDepthTest, float flDuration )
  543. {
  544. // Setup our transform matrix
  545. matrix3x4_t xform;
  546. AngleMatrix( angles, position, xform );
  547. Vector xAxis, yAxis, zAxis;
  548. // default draws circle in the y/z plane
  549. MatrixGetColumn( xform, 0, xAxis );
  550. MatrixGetColumn( xform, 1, yAxis );
  551. MatrixGetColumn( xform, 2, zAxis );
  552. Circle( position, xAxis, yAxis, radius, r, g, b, a, bNoDepthTest, flDuration ); // xy plane
  553. Circle( position, yAxis, zAxis, radius, r, g, b, a, bNoDepthTest, flDuration ); // yz plane
  554. Circle( position, xAxis, zAxis, radius, r, g, b, a, bNoDepthTest, flDuration ); // xz plane
  555. }