From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/game/shared/debugoverlay_shared.cpp | 1322 ++++++++++++++-------------- 1 file changed, 661 insertions(+), 661 deletions(-) (limited to 'mp/src/game/shared/debugoverlay_shared.cpp') diff --git a/mp/src/game/shared/debugoverlay_shared.cpp b/mp/src/game/shared/debugoverlay_shared.cpp index 0c5faabf..8ed8e1c9 100644 --- a/mp/src/game/shared/debugoverlay_shared.cpp +++ b/mp/src/game/shared/debugoverlay_shared.cpp @@ -1,661 +1,661 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Utility functions for using debug overlays to visualize information -// in the world. Uses the IVDebugOverlay interface. -// -//=============================================================================// - -#include "cbase.h" -#include "debugoverlay_shared.h" -#include "mathlib/mathlib.h" - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - -#define MAX_OVERLAY_DIST_SQR 90000000 - -//----------------------------------------------------------------------------- -// Purpose: Local player on the server or client -//----------------------------------------------------------------------------- -CBasePlayer *GetLocalPlayer( void ) -{ -#if defined( CLIENT_DLL) - return C_BasePlayer::GetLocalPlayer(); -#else - return UTIL_GetListenServerHost(); -#endif -} - -//----------------------------------------------------------------------------- -// Purpose: Debug player by index -//----------------------------------------------------------------------------- -CBasePlayer *GetDebugPlayer( void ) -{ -#if defined( CLIENT_DLL ) - //NOTENOTE: This doesn't necessarily make sense on the client - return GetLocalPlayer(); -#else - return UTIL_PlayerByIndex(CBaseEntity::m_nDebugPlayer); -#endif -} - -//----------------------------------------------------------------------------- -// Purpose: Draw a box with no orientation -//----------------------------------------------------------------------------- -void NDebugOverlay::Box(const Vector &origin, const Vector &mins, const Vector &maxs, int r, int g, int b, int a, float flDuration) -{ - BoxAngles( origin, mins, maxs, vec3_angle, r, g, b, a, flDuration ); -} - -//----------------------------------------------------------------------------- -// Purpose: Draw box oriented to a Vector direction -//----------------------------------------------------------------------------- -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) -{ - // convert forward vector to angles - QAngle f_angles = vec3_angle; - f_angles.y = UTIL_VecToYaw( orientation ); - - BoxAngles( origin, mins, maxs, f_angles, r, g, b, a, duration ); -} - -//----------------------------------------------------------------------------- -// Purpose: Draw box oriented to a QAngle direction -//----------------------------------------------------------------------------- -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) -{ - if ( debugoverlay ) - { - debugoverlay->AddBoxOverlay( origin, mins, maxs, angles, r, g, b, a, duration ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Draws a swept box -//----------------------------------------------------------------------------- -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) -{ - if ( debugoverlay ) - { - debugoverlay->AddSweptBoxOverlay( start, end, mins, maxs, angles, r, g, b, a, flDuration ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Draws a box around an entity -//----------------------------------------------------------------------------- -void NDebugOverlay::EntityBounds( const CBaseEntity *pEntity, int r, int g, int b, int a, float flDuration ) -{ - const CCollisionProperty *pCollide = pEntity->CollisionProp(); - BoxAngles( pCollide->GetCollisionOrigin(), pCollide->OBBMins(), pCollide->OBBMaxs(), pCollide->GetCollisionAngles(), r, g, b, a, flDuration ); -} - -//----------------------------------------------------------------------------- -// Purpose: Draws a line from one position to another -//----------------------------------------------------------------------------- -void NDebugOverlay::Line( const Vector &origin, const Vector &target, int r, int g, int b, bool noDepthTest, float duration ) -{ - // -------------------------------------------------------------- - // Clip the line before sending so we - // don't overflow the client message buffer - // -------------------------------------------------------------- - CBasePlayer *player = GetLocalPlayer(); - - if ( player == NULL ) - return; - - // Clip line that is far away - if (((player->GetAbsOrigin() - origin).LengthSqr() > MAX_OVERLAY_DIST_SQR) && - ((player->GetAbsOrigin() - target).LengthSqr() > MAX_OVERLAY_DIST_SQR) ) - return; - - // Clip line that is behind the client - Vector clientForward; - player->EyeVectors( &clientForward ); - - Vector toOrigin = origin - player->GetAbsOrigin(); - Vector toTarget = target - player->GetAbsOrigin(); - float dotOrigin = DotProduct(clientForward,toOrigin); - float dotTarget = DotProduct(clientForward,toTarget); - - if (dotOrigin < 0 && dotTarget < 0) - return; - - if ( debugoverlay ) - { - debugoverlay->AddLineOverlay( origin, target, r, g, b, noDepthTest, duration ); - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Draw triangle -//----------------------------------------------------------------------------- -void NDebugOverlay::Triangle( const Vector &p1, const Vector &p2, const Vector &p3, int r, int g, int b, int a, bool noDepthTest, float duration ) -{ - CBasePlayer *player = GetLocalPlayer(); - if ( !player ) - return; - - // Clip triangles that are far away - Vector to1 = p1 - player->GetAbsOrigin(); - Vector to2 = p2 - player->GetAbsOrigin(); - Vector to3 = p3 - player->GetAbsOrigin(); - - if ((to1.LengthSqr() > MAX_OVERLAY_DIST_SQR) && - (to2.LengthSqr() > MAX_OVERLAY_DIST_SQR) && - (to3.LengthSqr() > MAX_OVERLAY_DIST_SQR)) - { - return; - } - - // Clip triangles that are behind the client - Vector clientForward; - player->EyeVectors( &clientForward ); - - float dot1 = DotProduct(clientForward, to1); - float dot2 = DotProduct(clientForward, to2); - float dot3 = DotProduct(clientForward, to3); - - if (dot1 < 0 && dot2 < 0 && dot3 < 0) - return; - - if ( debugoverlay ) - { - debugoverlay->AddTriangleOverlay( p1, p2, p3, r, g, b, a, noDepthTest, duration ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Draw entity text overlay -//----------------------------------------------------------------------------- -void NDebugOverlay::EntityText( int entityID, int text_offset, const char *text, float duration, int r, int g, int b, int a ) -{ - if ( debugoverlay ) - { - debugoverlay->AddEntityTextOverlay( entityID, text_offset, duration, - (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), - (int)clamp(a * 255.f,0.f,255.f), text ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Draw entity text overlay at a specific position -//----------------------------------------------------------------------------- -void NDebugOverlay::EntityTextAtPosition( const Vector &origin, int text_offset, const char *text, float duration, int r, int g, int b, int a ) -{ - if ( debugoverlay ) - { - debugoverlay->AddTextOverlayRGB( origin, text_offset, duration, r, g, b, a, "%s", text ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Add grid overlay -//----------------------------------------------------------------------------- -void NDebugOverlay::Grid( const Vector &vPosition ) -{ - if ( debugoverlay ) - { - debugoverlay->AddGridOverlay( vPosition ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Draw debug text at a position -//----------------------------------------------------------------------------- -void NDebugOverlay::Text( const Vector &origin, const char *text, bool bViewCheck, float duration ) -{ - CBasePlayer *player = GetLocalPlayer(); - - if ( !player ) - return; - - // Clip text that is far away - if ( ( player->GetAbsOrigin() - origin ).LengthSqr() > MAX_OVERLAY_DIST_SQR ) - return; - - // Clip text that is behind the client - Vector clientForward; - player->EyeVectors( &clientForward ); - - Vector toText = origin - player->GetAbsOrigin(); - float dotPr = DotProduct(clientForward,toText); - - if (dotPr < 0) - return; - - // Clip text that is obscured - if (bViewCheck) - { - trace_t tr; - UTIL_TraceLine(player->GetAbsOrigin(), origin, MASK_OPAQUE, NULL, COLLISION_GROUP_NONE, &tr); - - if ((tr.endpos - origin).Length() > 10) - return; - } - - if ( debugoverlay ) - { - debugoverlay->AddTextOverlay( origin, duration, "%s", text ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Add debug overlay text with screen position -//----------------------------------------------------------------------------- -void NDebugOverlay::ScreenText( float flXpos, float flYpos, const char *text, int r, int g, int b, int a, float duration ) -{ - if ( debugoverlay ) - { - debugoverlay->AddScreenTextOverlay( flXpos, flYpos, duration, r, g, b, a, text ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Draw a colored 3D cross of the given hull size at the given position -//----------------------------------------------------------------------------- -void NDebugOverlay::Cross3D(const Vector &position, const Vector &mins, const Vector &maxs, int r, int g, int b, bool noDepthTest, float fDuration ) -{ - Vector start = mins + position; - Vector end = maxs + position; - Line(start,end, r, g, b, noDepthTest,fDuration); - - start.x += (maxs.x - mins.x); - end.x -= (maxs.x - mins.x); - Line(start,end, r, g, b, noDepthTest,fDuration); - - start.y += (maxs.y - mins.y); - end.y -= (maxs.y - mins.y); - Line(start,end, r, g, b, noDepthTest,fDuration); - - start.x -= (maxs.x - mins.x); - end.x += (maxs.x - mins.x); - Line(start,end, r, g, b, noDepthTest,fDuration); -} - -//----------------------------------------------------------------------------- -// Purpose: Draw a colored 3D cross of the given size at the given position -//----------------------------------------------------------------------------- -void NDebugOverlay::Cross3D(const Vector &position, float size, int r, int g, int b, bool noDepthTest, float flDuration ) -{ - Line( position + Vector(size,0,0), position - Vector(size,0,0), r, g, b, noDepthTest, flDuration ); - Line( position + Vector(0,size,0), position - Vector(0,size,0), r, g, b, noDepthTest, flDuration ); - Line( position + Vector(0,0,size), position - Vector(0,0,size), r, g, b, noDepthTest, flDuration ); -} - -//----------------------------------------------------------------------------- -// Purpose: Draw an oriented, colored 3D cross of the given size at the given position (via a vector) -//----------------------------------------------------------------------------- -void NDebugOverlay::Cross3DOriented( const Vector &position, const QAngle &angles, float size, int r, int g, int b, bool noDepthTest, float flDuration ) -{ - Vector forward, right, up; - AngleVectors( angles, &forward, &right, &up ); - - forward *= size; - right *= size; - up *= size; - - Line( position + right, position - right, r, g, b, noDepthTest, flDuration ); - Line( position + forward, position - forward, r, g, b, noDepthTest, flDuration ); - Line( position + up, position - up, r, g, b, noDepthTest, flDuration ); -} - -//----------------------------------------------------------------------------- -// Purpose: Draw an oriented, colored 3D cross of the given size at the given position (via a matrix) -//----------------------------------------------------------------------------- -void NDebugOverlay::Cross3DOriented( const matrix3x4_t &m, float size, int c, bool noDepthTest, float flDuration ) -{ - Vector forward, left, up, position; - - MatrixGetColumn( m, 0, forward ); - MatrixGetColumn( m, 1, left ); - MatrixGetColumn( m, 2, up ); - MatrixGetColumn( m, 3, position ); - - forward *= size; - left *= size; - up *= size; - - Line( position + left, position - left, 0, c, 0, noDepthTest, flDuration ); - Line( position + forward, position - forward, c, 0, 0, noDepthTest, flDuration ); - Line( position + up, position - up, 0, 0, c, noDepthTest, flDuration ); -} - -//-------------------------------------------------------------------------------- -// Purpose : Draw tick marks between start and end position of the given distance -// with text every tickTextDist steps apart. -//-------------------------------------------------------------------------------- -void NDebugOverlay::DrawTickMarkedLine(const Vector &startPos, const Vector &endPos, float tickDist, int tickTextDist, int r, int g, int b, bool noDepthTest, float duration ) -{ - CBasePlayer* pPlayer = GetDebugPlayer(); - - if ( !pPlayer ) - return; - - Vector lineDir = (endPos - startPos); - float lineDist = VectorNormalize( lineDir ); - int numTicks = lineDist/tickDist; - Vector vBodyDir; - -#if defined( CLIENT_DLL ) - AngleVectors( pPlayer->LocalEyeAngles(), &vBodyDir ); -#else - vBodyDir = pPlayer->BodyDirection2D( ); -#endif - - Vector upVec = 4*vBodyDir; - Vector sideDir; - Vector tickPos = startPos; - int tickTextCnt = 0; - - CrossProduct(lineDir, upVec, sideDir); - - // First draw the line - Line(startPos, endPos, r,g,b,noDepthTest,duration); - - // Now draw the ticks - for (int i=0;iEyePosition(); - pPlayer->EyeVectors( &vForward ); - - trace_t tr; - UTIL_TraceLine ( vSource, vSource + vForward * 2048, MASK_SOLID, pPlayer, COLLISION_GROUP_NONE, &tr); - float dotPr = DotProduct(Vector(0,0,1),tr.plane.normal); - if (tr.fraction != 1.0 && dotPr > 0.5) - { - tr.endpos.z += 1; - float scale = 6; - Vector startPos = tr.endpos + Vector (-scale,0,0); - Vector endPos = tr.endpos + Vector ( scale,0,0); - Line(startPos, endPos, 255, 0, 0,false,0); - - startPos = tr.endpos + Vector (0,-scale,0); - endPos = tr.endpos + Vector (0, scale,0); - Line(startPos, endPos, 255, 0, 0,false,0); - } -} - -//-------------------------------------------------------------------------------- -// Purpose : Draw a horizontal arrow pointing in the specified direction -//-------------------------------------------------------------------------------- -void NDebugOverlay::HorzArrow( const Vector &startPos, const Vector &endPos, float width, int r, int g, int b, int a, bool noDepthTest, float flDuration) -{ - Vector lineDir = (endPos - startPos); - VectorNormalize( lineDir ); - Vector upVec = Vector( 0, 0, 1 ); - Vector sideDir; - float radius = width / 2.0; - - CrossProduct(lineDir, upVec, sideDir); - - Vector p1 = startPos - sideDir * radius; - Vector p2 = endPos - lineDir * width - sideDir * radius; - Vector p3 = endPos - lineDir * width - sideDir * width; - Vector p4 = endPos; - Vector p5 = endPos - lineDir * width + sideDir * width; - Vector p6 = endPos - lineDir * width + sideDir * radius; - Vector p7 = startPos + sideDir * radius; - - // Outline the arrow - Line(p1, p2, r,g,b,noDepthTest,flDuration); - Line(p2, p3, r,g,b,noDepthTest,flDuration); - Line(p3, p4, r,g,b,noDepthTest,flDuration); - Line(p4, p5, r,g,b,noDepthTest,flDuration); - Line(p5, p6, r,g,b,noDepthTest,flDuration); - Line(p6, p7, r,g,b,noDepthTest,flDuration); - - if ( a > 0 ) - { - // Fill us in with triangles - Triangle( p5, p4, p3, r, g, b, a, noDepthTest, flDuration ); // Tip - Triangle( p1, p7, p6, r, g, b, a, noDepthTest, flDuration ); // Shaft - Triangle( p6, p2, p1, r, g, b, a, noDepthTest, flDuration ); - - // And backfaces - Triangle( p3, p4, p5, r, g, b, a, noDepthTest, flDuration ); // Tip - Triangle( p6, p7, p1, r, g, b, a, noDepthTest, flDuration ); // Shaft - Triangle( p1, p2, p6, r, g, b, a, noDepthTest, flDuration ); - } -} - -//----------------------------------------------------------------------------- -// Purpose : Draw a horizontal arrow pointing in the specified direction by yaw value -//----------------------------------------------------------------------------- -void NDebugOverlay::YawArrow( const Vector &startPos, float yaw, float length, float width, int r, int g, int b, int a, bool noDepthTest, float flDuration) -{ - Vector forward = UTIL_YawToVector( yaw ); - - HorzArrow( startPos, startPos + forward * length, width, r, g, b, a, noDepthTest, flDuration ); -} - -//-------------------------------------------------------------------------------- -// Purpose : Draw a vertical arrow at a position -//-------------------------------------------------------------------------------- -void NDebugOverlay::VertArrow( const Vector &startPos, const Vector &endPos, float width, int r, int g, int b, int a, bool noDepthTest, float flDuration) -{ - Vector lineDir = (endPos - startPos); - VectorNormalize( lineDir ); - Vector upVec; - Vector sideDir; - float radius = width / 2.0; - - VectorVectors( lineDir, sideDir, upVec ); - - Vector p1 = startPos - upVec * radius; - Vector p2 = endPos - lineDir * width - upVec * radius; - Vector p3 = endPos - lineDir * width - upVec * width; - Vector p4 = endPos; - Vector p5 = endPos - lineDir * width + upVec * width; - Vector p6 = endPos - lineDir * width + upVec * radius; - Vector p7 = startPos + upVec * radius; - - // Outline the arrow - Line(p1, p2, r,g,b,noDepthTest,flDuration); - Line(p2, p3, r,g,b,noDepthTest,flDuration); - Line(p3, p4, r,g,b,noDepthTest,flDuration); - Line(p4, p5, r,g,b,noDepthTest,flDuration); - Line(p5, p6, r,g,b,noDepthTest,flDuration); - Line(p6, p7, r,g,b,noDepthTest,flDuration); - - if ( a > 0 ) - { - // Fill us in with triangles - Triangle( p5, p4, p3, r, g, b, a, noDepthTest, flDuration ); // Tip - Triangle( p1, p7, p6, r, g, b, a, noDepthTest, flDuration ); // Shaft - Triangle( p6, p2, p1, r, g, b, a, noDepthTest, flDuration ); - - // And backfaces - Triangle( p3, p4, p5, r, g, b, a, noDepthTest, flDuration ); // Tip - Triangle( p6, p7, p1, r, g, b, a, noDepthTest, flDuration ); // Shaft - Triangle( p1, p2, p6, r, g, b, a, noDepthTest, flDuration ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Draw an axis -//----------------------------------------------------------------------------- -void NDebugOverlay::Axis( const Vector &position, const QAngle &angles, float size, bool noDepthTest, float flDuration ) -{ - Vector xvec, yvec, zvec; - AngleVectors( angles, &xvec, &yvec, &zvec ); - - xvec = position + (size * xvec); - yvec = position - (size * yvec); // Left is positive - zvec = position + (size * zvec); - - Line( position, xvec, 255, 0, 0, noDepthTest, flDuration ); - Line( position, yvec, 0, 255, 0, noDepthTest, flDuration ); - Line( position, zvec, 0, 0, 255, noDepthTest, flDuration ); -} - -//----------------------------------------------------------------------------- -// Purpose: Draw circles to suggest a sphere -//----------------------------------------------------------------------------- -void NDebugOverlay::Sphere( const Vector ¢er, float radius, int r, int g, int b, bool noDepthTest, float flDuration ) -{ - Vector edge, lastEdge; - - float axisSize = radius; - Line( center + Vector( 0, 0, -axisSize ), center + Vector( 0, 0, axisSize ), r, g, b, noDepthTest, flDuration ); - Line( center + Vector( 0, -axisSize, 0 ), center + Vector( 0, axisSize, 0 ), r, g, b, noDepthTest, flDuration ); - Line( center + Vector( -axisSize, 0, 0 ), center + Vector( axisSize, 0, 0 ), r, g, b, noDepthTest, flDuration ); - - lastEdge = Vector( radius + center.x, center.y, center.z ); - float angle; - for( angle=0.0f; angle <= 360.0f; angle += 22.5f ) - { - edge.x = radius * cosf( angle / 180.0f * M_PI ) + center.x; - edge.y = center.y; - edge.z = radius * sinf( angle / 180.0f * M_PI ) + center.z; - - Line( edge, lastEdge, r, g, b, noDepthTest, flDuration ); - - lastEdge = edge; - } - - lastEdge = Vector( center.x, radius + center.y, center.z ); - for( angle=0.0f; angle <= 360.0f; angle += 22.5f ) - { - edge.x = center.x; - edge.y = radius * cosf( angle / 180.0f * M_PI ) + center.y; - edge.z = radius * sinf( angle / 180.0f * M_PI ) + center.z; - - Line( edge, lastEdge, r, g, b, noDepthTest, flDuration ); - - lastEdge = edge; - } - - lastEdge = Vector( center.x, radius + center.y, center.z ); - for( angle=0.0f; angle <= 360.0f; angle += 22.5f ) - { - edge.x = radius * cosf( angle / 180.0f * M_PI ) + center.x; - edge.y = radius * sinf( angle / 180.0f * M_PI ) + center.y; - edge.z = center.z; - - Line( edge, lastEdge, r, g, b, noDepthTest, flDuration ); - - lastEdge = edge; - } -} - -//----------------------------------------------------------------------------- -// Purpose: Draw a circle whose center is at a position, facing the camera -//----------------------------------------------------------------------------- -void NDebugOverlay::Circle( const Vector &position, float radius, int r, int g, int b, int a, bool bNoDepthTest, float flDuration ) -{ - CBasePlayer *player = GetLocalPlayer(); - if ( player == NULL ) - return; - - Vector clientForward; - player->EyeVectors( &clientForward ); - - QAngle vecAngles; - VectorAngles( clientForward, vecAngles ); - - Circle( position, vecAngles, radius, r, g, b, a, bNoDepthTest, flDuration ); -} - - -//----------------------------------------------------------------------------- -// Purpose: Draw a circle whose center is at a position and is facing a specified direction -//----------------------------------------------------------------------------- -void NDebugOverlay::Circle( const Vector &position, const QAngle &angles, float radius, int r, int g, int b, int a, bool bNoDepthTest, float flDuration ) -{ - // Setup our transform matrix - matrix3x4_t xform; - AngleMatrix( angles, position, xform ); - Vector xAxis, yAxis; - // default draws circle in the y/z plane - MatrixGetColumn( xform, 2, xAxis ); - MatrixGetColumn( xform, 1, yAxis ); - Circle( position, xAxis, yAxis, radius, r, g, b, a, bNoDepthTest, flDuration ); -} - -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 ) -{ - const unsigned int nSegments = 16; - const float flRadStep = (M_PI*2.0f) / (float) nSegments; - - Vector vecLastPosition; - - // Find our first position - // Retained for triangle fanning - Vector vecStart = position + xAxis * radius; - Vector vecPosition = vecStart; - - // Draw out each segment (fanning triangles if we have an alpha amount) - for ( int i = 1; i <= nSegments; i++ ) - { - // Store off our last position - vecLastPosition = vecPosition; - - // Calculate the new one - float flSin, flCos; - SinCos( flRadStep*i, &flSin, &flCos ); - vecPosition = position + (xAxis * flCos * radius) + (yAxis * flSin * radius); - - // Draw the line - Line( vecLastPosition, vecPosition, r, g, b, bNoDepthTest, flDuration ); - - // If we have an alpha value, then draw the fan - if ( a && i > 1 ) - { - debugoverlay->AddTriangleOverlay( vecStart, vecLastPosition, vecPosition, r, g, b, a, bNoDepthTest, flDuration ); - } - } -} - -void NDebugOverlay::Sphere( const Vector &position, const QAngle &angles, float radius, int r, int g, int b, int a, bool bNoDepthTest, float flDuration ) -{ - // Setup our transform matrix - matrix3x4_t xform; - AngleMatrix( angles, position, xform ); - Vector xAxis, yAxis, zAxis; - // default draws circle in the y/z plane - MatrixGetColumn( xform, 0, xAxis ); - MatrixGetColumn( xform, 1, yAxis ); - MatrixGetColumn( xform, 2, zAxis ); - Circle( position, xAxis, yAxis, radius, r, g, b, a, bNoDepthTest, flDuration ); // xy plane - Circle( position, yAxis, zAxis, radius, r, g, b, a, bNoDepthTest, flDuration ); // yz plane - Circle( position, xAxis, zAxis, radius, r, g, b, a, bNoDepthTest, flDuration ); // xz plane -} +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Utility functions for using debug overlays to visualize information +// in the world. Uses the IVDebugOverlay interface. +// +//=============================================================================// + +#include "cbase.h" +#include "debugoverlay_shared.h" +#include "mathlib/mathlib.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define MAX_OVERLAY_DIST_SQR 90000000 + +//----------------------------------------------------------------------------- +// Purpose: Local player on the server or client +//----------------------------------------------------------------------------- +CBasePlayer *GetLocalPlayer( void ) +{ +#if defined( CLIENT_DLL) + return C_BasePlayer::GetLocalPlayer(); +#else + return UTIL_GetListenServerHost(); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: Debug player by index +//----------------------------------------------------------------------------- +CBasePlayer *GetDebugPlayer( void ) +{ +#if defined( CLIENT_DLL ) + //NOTENOTE: This doesn't necessarily make sense on the client + return GetLocalPlayer(); +#else + return UTIL_PlayerByIndex(CBaseEntity::m_nDebugPlayer); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: Draw a box with no orientation +//----------------------------------------------------------------------------- +void NDebugOverlay::Box(const Vector &origin, const Vector &mins, const Vector &maxs, int r, int g, int b, int a, float flDuration) +{ + BoxAngles( origin, mins, maxs, vec3_angle, r, g, b, a, flDuration ); +} + +//----------------------------------------------------------------------------- +// Purpose: Draw box oriented to a Vector direction +//----------------------------------------------------------------------------- +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) +{ + // convert forward vector to angles + QAngle f_angles = vec3_angle; + f_angles.y = UTIL_VecToYaw( orientation ); + + BoxAngles( origin, mins, maxs, f_angles, r, g, b, a, duration ); +} + +//----------------------------------------------------------------------------- +// Purpose: Draw box oriented to a QAngle direction +//----------------------------------------------------------------------------- +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) +{ + if ( debugoverlay ) + { + debugoverlay->AddBoxOverlay( origin, mins, maxs, angles, r, g, b, a, duration ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Draws a swept box +//----------------------------------------------------------------------------- +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) +{ + if ( debugoverlay ) + { + debugoverlay->AddSweptBoxOverlay( start, end, mins, maxs, angles, r, g, b, a, flDuration ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Draws a box around an entity +//----------------------------------------------------------------------------- +void NDebugOverlay::EntityBounds( const CBaseEntity *pEntity, int r, int g, int b, int a, float flDuration ) +{ + const CCollisionProperty *pCollide = pEntity->CollisionProp(); + BoxAngles( pCollide->GetCollisionOrigin(), pCollide->OBBMins(), pCollide->OBBMaxs(), pCollide->GetCollisionAngles(), r, g, b, a, flDuration ); +} + +//----------------------------------------------------------------------------- +// Purpose: Draws a line from one position to another +//----------------------------------------------------------------------------- +void NDebugOverlay::Line( const Vector &origin, const Vector &target, int r, int g, int b, bool noDepthTest, float duration ) +{ + // -------------------------------------------------------------- + // Clip the line before sending so we + // don't overflow the client message buffer + // -------------------------------------------------------------- + CBasePlayer *player = GetLocalPlayer(); + + if ( player == NULL ) + return; + + // Clip line that is far away + if (((player->GetAbsOrigin() - origin).LengthSqr() > MAX_OVERLAY_DIST_SQR) && + ((player->GetAbsOrigin() - target).LengthSqr() > MAX_OVERLAY_DIST_SQR) ) + return; + + // Clip line that is behind the client + Vector clientForward; + player->EyeVectors( &clientForward ); + + Vector toOrigin = origin - player->GetAbsOrigin(); + Vector toTarget = target - player->GetAbsOrigin(); + float dotOrigin = DotProduct(clientForward,toOrigin); + float dotTarget = DotProduct(clientForward,toTarget); + + if (dotOrigin < 0 && dotTarget < 0) + return; + + if ( debugoverlay ) + { + debugoverlay->AddLineOverlay( origin, target, r, g, b, noDepthTest, duration ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Draw triangle +//----------------------------------------------------------------------------- +void NDebugOverlay::Triangle( const Vector &p1, const Vector &p2, const Vector &p3, int r, int g, int b, int a, bool noDepthTest, float duration ) +{ + CBasePlayer *player = GetLocalPlayer(); + if ( !player ) + return; + + // Clip triangles that are far away + Vector to1 = p1 - player->GetAbsOrigin(); + Vector to2 = p2 - player->GetAbsOrigin(); + Vector to3 = p3 - player->GetAbsOrigin(); + + if ((to1.LengthSqr() > MAX_OVERLAY_DIST_SQR) && + (to2.LengthSqr() > MAX_OVERLAY_DIST_SQR) && + (to3.LengthSqr() > MAX_OVERLAY_DIST_SQR)) + { + return; + } + + // Clip triangles that are behind the client + Vector clientForward; + player->EyeVectors( &clientForward ); + + float dot1 = DotProduct(clientForward, to1); + float dot2 = DotProduct(clientForward, to2); + float dot3 = DotProduct(clientForward, to3); + + if (dot1 < 0 && dot2 < 0 && dot3 < 0) + return; + + if ( debugoverlay ) + { + debugoverlay->AddTriangleOverlay( p1, p2, p3, r, g, b, a, noDepthTest, duration ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Draw entity text overlay +//----------------------------------------------------------------------------- +void NDebugOverlay::EntityText( int entityID, int text_offset, const char *text, float duration, int r, int g, int b, int a ) +{ + if ( debugoverlay ) + { + debugoverlay->AddEntityTextOverlay( entityID, text_offset, duration, + (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), + (int)clamp(a * 255.f,0.f,255.f), text ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Draw entity text overlay at a specific position +//----------------------------------------------------------------------------- +void NDebugOverlay::EntityTextAtPosition( const Vector &origin, int text_offset, const char *text, float duration, int r, int g, int b, int a ) +{ + if ( debugoverlay ) + { + debugoverlay->AddTextOverlayRGB( origin, text_offset, duration, r, g, b, a, "%s", text ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Add grid overlay +//----------------------------------------------------------------------------- +void NDebugOverlay::Grid( const Vector &vPosition ) +{ + if ( debugoverlay ) + { + debugoverlay->AddGridOverlay( vPosition ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Draw debug text at a position +//----------------------------------------------------------------------------- +void NDebugOverlay::Text( const Vector &origin, const char *text, bool bViewCheck, float duration ) +{ + CBasePlayer *player = GetLocalPlayer(); + + if ( !player ) + return; + + // Clip text that is far away + if ( ( player->GetAbsOrigin() - origin ).LengthSqr() > MAX_OVERLAY_DIST_SQR ) + return; + + // Clip text that is behind the client + Vector clientForward; + player->EyeVectors( &clientForward ); + + Vector toText = origin - player->GetAbsOrigin(); + float dotPr = DotProduct(clientForward,toText); + + if (dotPr < 0) + return; + + // Clip text that is obscured + if (bViewCheck) + { + trace_t tr; + UTIL_TraceLine(player->GetAbsOrigin(), origin, MASK_OPAQUE, NULL, COLLISION_GROUP_NONE, &tr); + + if ((tr.endpos - origin).Length() > 10) + return; + } + + if ( debugoverlay ) + { + debugoverlay->AddTextOverlay( origin, duration, "%s", text ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Add debug overlay text with screen position +//----------------------------------------------------------------------------- +void NDebugOverlay::ScreenText( float flXpos, float flYpos, const char *text, int r, int g, int b, int a, float duration ) +{ + if ( debugoverlay ) + { + debugoverlay->AddScreenTextOverlay( flXpos, flYpos, duration, r, g, b, a, text ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Draw a colored 3D cross of the given hull size at the given position +//----------------------------------------------------------------------------- +void NDebugOverlay::Cross3D(const Vector &position, const Vector &mins, const Vector &maxs, int r, int g, int b, bool noDepthTest, float fDuration ) +{ + Vector start = mins + position; + Vector end = maxs + position; + Line(start,end, r, g, b, noDepthTest,fDuration); + + start.x += (maxs.x - mins.x); + end.x -= (maxs.x - mins.x); + Line(start,end, r, g, b, noDepthTest,fDuration); + + start.y += (maxs.y - mins.y); + end.y -= (maxs.y - mins.y); + Line(start,end, r, g, b, noDepthTest,fDuration); + + start.x -= (maxs.x - mins.x); + end.x += (maxs.x - mins.x); + Line(start,end, r, g, b, noDepthTest,fDuration); +} + +//----------------------------------------------------------------------------- +// Purpose: Draw a colored 3D cross of the given size at the given position +//----------------------------------------------------------------------------- +void NDebugOverlay::Cross3D(const Vector &position, float size, int r, int g, int b, bool noDepthTest, float flDuration ) +{ + Line( position + Vector(size,0,0), position - Vector(size,0,0), r, g, b, noDepthTest, flDuration ); + Line( position + Vector(0,size,0), position - Vector(0,size,0), r, g, b, noDepthTest, flDuration ); + Line( position + Vector(0,0,size), position - Vector(0,0,size), r, g, b, noDepthTest, flDuration ); +} + +//----------------------------------------------------------------------------- +// Purpose: Draw an oriented, colored 3D cross of the given size at the given position (via a vector) +//----------------------------------------------------------------------------- +void NDebugOverlay::Cross3DOriented( const Vector &position, const QAngle &angles, float size, int r, int g, int b, bool noDepthTest, float flDuration ) +{ + Vector forward, right, up; + AngleVectors( angles, &forward, &right, &up ); + + forward *= size; + right *= size; + up *= size; + + Line( position + right, position - right, r, g, b, noDepthTest, flDuration ); + Line( position + forward, position - forward, r, g, b, noDepthTest, flDuration ); + Line( position + up, position - up, r, g, b, noDepthTest, flDuration ); +} + +//----------------------------------------------------------------------------- +// Purpose: Draw an oriented, colored 3D cross of the given size at the given position (via a matrix) +//----------------------------------------------------------------------------- +void NDebugOverlay::Cross3DOriented( const matrix3x4_t &m, float size, int c, bool noDepthTest, float flDuration ) +{ + Vector forward, left, up, position; + + MatrixGetColumn( m, 0, forward ); + MatrixGetColumn( m, 1, left ); + MatrixGetColumn( m, 2, up ); + MatrixGetColumn( m, 3, position ); + + forward *= size; + left *= size; + up *= size; + + Line( position + left, position - left, 0, c, 0, noDepthTest, flDuration ); + Line( position + forward, position - forward, c, 0, 0, noDepthTest, flDuration ); + Line( position + up, position - up, 0, 0, c, noDepthTest, flDuration ); +} + +//-------------------------------------------------------------------------------- +// Purpose : Draw tick marks between start and end position of the given distance +// with text every tickTextDist steps apart. +//-------------------------------------------------------------------------------- +void NDebugOverlay::DrawTickMarkedLine(const Vector &startPos, const Vector &endPos, float tickDist, int tickTextDist, int r, int g, int b, bool noDepthTest, float duration ) +{ + CBasePlayer* pPlayer = GetDebugPlayer(); + + if ( !pPlayer ) + return; + + Vector lineDir = (endPos - startPos); + float lineDist = VectorNormalize( lineDir ); + int numTicks = lineDist/tickDist; + Vector vBodyDir; + +#if defined( CLIENT_DLL ) + AngleVectors( pPlayer->LocalEyeAngles(), &vBodyDir ); +#else + vBodyDir = pPlayer->BodyDirection2D( ); +#endif + + Vector upVec = 4*vBodyDir; + Vector sideDir; + Vector tickPos = startPos; + int tickTextCnt = 0; + + CrossProduct(lineDir, upVec, sideDir); + + // First draw the line + Line(startPos, endPos, r,g,b,noDepthTest,duration); + + // Now draw the ticks + for (int i=0;iEyePosition(); + pPlayer->EyeVectors( &vForward ); + + trace_t tr; + UTIL_TraceLine ( vSource, vSource + vForward * 2048, MASK_SOLID, pPlayer, COLLISION_GROUP_NONE, &tr); + float dotPr = DotProduct(Vector(0,0,1),tr.plane.normal); + if (tr.fraction != 1.0 && dotPr > 0.5) + { + tr.endpos.z += 1; + float scale = 6; + Vector startPos = tr.endpos + Vector (-scale,0,0); + Vector endPos = tr.endpos + Vector ( scale,0,0); + Line(startPos, endPos, 255, 0, 0,false,0); + + startPos = tr.endpos + Vector (0,-scale,0); + endPos = tr.endpos + Vector (0, scale,0); + Line(startPos, endPos, 255, 0, 0,false,0); + } +} + +//-------------------------------------------------------------------------------- +// Purpose : Draw a horizontal arrow pointing in the specified direction +//-------------------------------------------------------------------------------- +void NDebugOverlay::HorzArrow( const Vector &startPos, const Vector &endPos, float width, int r, int g, int b, int a, bool noDepthTest, float flDuration) +{ + Vector lineDir = (endPos - startPos); + VectorNormalize( lineDir ); + Vector upVec = Vector( 0, 0, 1 ); + Vector sideDir; + float radius = width / 2.0; + + CrossProduct(lineDir, upVec, sideDir); + + Vector p1 = startPos - sideDir * radius; + Vector p2 = endPos - lineDir * width - sideDir * radius; + Vector p3 = endPos - lineDir * width - sideDir * width; + Vector p4 = endPos; + Vector p5 = endPos - lineDir * width + sideDir * width; + Vector p6 = endPos - lineDir * width + sideDir * radius; + Vector p7 = startPos + sideDir * radius; + + // Outline the arrow + Line(p1, p2, r,g,b,noDepthTest,flDuration); + Line(p2, p3, r,g,b,noDepthTest,flDuration); + Line(p3, p4, r,g,b,noDepthTest,flDuration); + Line(p4, p5, r,g,b,noDepthTest,flDuration); + Line(p5, p6, r,g,b,noDepthTest,flDuration); + Line(p6, p7, r,g,b,noDepthTest,flDuration); + + if ( a > 0 ) + { + // Fill us in with triangles + Triangle( p5, p4, p3, r, g, b, a, noDepthTest, flDuration ); // Tip + Triangle( p1, p7, p6, r, g, b, a, noDepthTest, flDuration ); // Shaft + Triangle( p6, p2, p1, r, g, b, a, noDepthTest, flDuration ); + + // And backfaces + Triangle( p3, p4, p5, r, g, b, a, noDepthTest, flDuration ); // Tip + Triangle( p6, p7, p1, r, g, b, a, noDepthTest, flDuration ); // Shaft + Triangle( p1, p2, p6, r, g, b, a, noDepthTest, flDuration ); + } +} + +//----------------------------------------------------------------------------- +// Purpose : Draw a horizontal arrow pointing in the specified direction by yaw value +//----------------------------------------------------------------------------- +void NDebugOverlay::YawArrow( const Vector &startPos, float yaw, float length, float width, int r, int g, int b, int a, bool noDepthTest, float flDuration) +{ + Vector forward = UTIL_YawToVector( yaw ); + + HorzArrow( startPos, startPos + forward * length, width, r, g, b, a, noDepthTest, flDuration ); +} + +//-------------------------------------------------------------------------------- +// Purpose : Draw a vertical arrow at a position +//-------------------------------------------------------------------------------- +void NDebugOverlay::VertArrow( const Vector &startPos, const Vector &endPos, float width, int r, int g, int b, int a, bool noDepthTest, float flDuration) +{ + Vector lineDir = (endPos - startPos); + VectorNormalize( lineDir ); + Vector upVec; + Vector sideDir; + float radius = width / 2.0; + + VectorVectors( lineDir, sideDir, upVec ); + + Vector p1 = startPos - upVec * radius; + Vector p2 = endPos - lineDir * width - upVec * radius; + Vector p3 = endPos - lineDir * width - upVec * width; + Vector p4 = endPos; + Vector p5 = endPos - lineDir * width + upVec * width; + Vector p6 = endPos - lineDir * width + upVec * radius; + Vector p7 = startPos + upVec * radius; + + // Outline the arrow + Line(p1, p2, r,g,b,noDepthTest,flDuration); + Line(p2, p3, r,g,b,noDepthTest,flDuration); + Line(p3, p4, r,g,b,noDepthTest,flDuration); + Line(p4, p5, r,g,b,noDepthTest,flDuration); + Line(p5, p6, r,g,b,noDepthTest,flDuration); + Line(p6, p7, r,g,b,noDepthTest,flDuration); + + if ( a > 0 ) + { + // Fill us in with triangles + Triangle( p5, p4, p3, r, g, b, a, noDepthTest, flDuration ); // Tip + Triangle( p1, p7, p6, r, g, b, a, noDepthTest, flDuration ); // Shaft + Triangle( p6, p2, p1, r, g, b, a, noDepthTest, flDuration ); + + // And backfaces + Triangle( p3, p4, p5, r, g, b, a, noDepthTest, flDuration ); // Tip + Triangle( p6, p7, p1, r, g, b, a, noDepthTest, flDuration ); // Shaft + Triangle( p1, p2, p6, r, g, b, a, noDepthTest, flDuration ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: Draw an axis +//----------------------------------------------------------------------------- +void NDebugOverlay::Axis( const Vector &position, const QAngle &angles, float size, bool noDepthTest, float flDuration ) +{ + Vector xvec, yvec, zvec; + AngleVectors( angles, &xvec, &yvec, &zvec ); + + xvec = position + (size * xvec); + yvec = position - (size * yvec); // Left is positive + zvec = position + (size * zvec); + + Line( position, xvec, 255, 0, 0, noDepthTest, flDuration ); + Line( position, yvec, 0, 255, 0, noDepthTest, flDuration ); + Line( position, zvec, 0, 0, 255, noDepthTest, flDuration ); +} + +//----------------------------------------------------------------------------- +// Purpose: Draw circles to suggest a sphere +//----------------------------------------------------------------------------- +void NDebugOverlay::Sphere( const Vector ¢er, float radius, int r, int g, int b, bool noDepthTest, float flDuration ) +{ + Vector edge, lastEdge; + + float axisSize = radius; + Line( center + Vector( 0, 0, -axisSize ), center + Vector( 0, 0, axisSize ), r, g, b, noDepthTest, flDuration ); + Line( center + Vector( 0, -axisSize, 0 ), center + Vector( 0, axisSize, 0 ), r, g, b, noDepthTest, flDuration ); + Line( center + Vector( -axisSize, 0, 0 ), center + Vector( axisSize, 0, 0 ), r, g, b, noDepthTest, flDuration ); + + lastEdge = Vector( radius + center.x, center.y, center.z ); + float angle; + for( angle=0.0f; angle <= 360.0f; angle += 22.5f ) + { + edge.x = radius * cosf( angle / 180.0f * M_PI ) + center.x; + edge.y = center.y; + edge.z = radius * sinf( angle / 180.0f * M_PI ) + center.z; + + Line( edge, lastEdge, r, g, b, noDepthTest, flDuration ); + + lastEdge = edge; + } + + lastEdge = Vector( center.x, radius + center.y, center.z ); + for( angle=0.0f; angle <= 360.0f; angle += 22.5f ) + { + edge.x = center.x; + edge.y = radius * cosf( angle / 180.0f * M_PI ) + center.y; + edge.z = radius * sinf( angle / 180.0f * M_PI ) + center.z; + + Line( edge, lastEdge, r, g, b, noDepthTest, flDuration ); + + lastEdge = edge; + } + + lastEdge = Vector( center.x, radius + center.y, center.z ); + for( angle=0.0f; angle <= 360.0f; angle += 22.5f ) + { + edge.x = radius * cosf( angle / 180.0f * M_PI ) + center.x; + edge.y = radius * sinf( angle / 180.0f * M_PI ) + center.y; + edge.z = center.z; + + Line( edge, lastEdge, r, g, b, noDepthTest, flDuration ); + + lastEdge = edge; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Draw a circle whose center is at a position, facing the camera +//----------------------------------------------------------------------------- +void NDebugOverlay::Circle( const Vector &position, float radius, int r, int g, int b, int a, bool bNoDepthTest, float flDuration ) +{ + CBasePlayer *player = GetLocalPlayer(); + if ( player == NULL ) + return; + + Vector clientForward; + player->EyeVectors( &clientForward ); + + QAngle vecAngles; + VectorAngles( clientForward, vecAngles ); + + Circle( position, vecAngles, radius, r, g, b, a, bNoDepthTest, flDuration ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Draw a circle whose center is at a position and is facing a specified direction +//----------------------------------------------------------------------------- +void NDebugOverlay::Circle( const Vector &position, const QAngle &angles, float radius, int r, int g, int b, int a, bool bNoDepthTest, float flDuration ) +{ + // Setup our transform matrix + matrix3x4_t xform; + AngleMatrix( angles, position, xform ); + Vector xAxis, yAxis; + // default draws circle in the y/z plane + MatrixGetColumn( xform, 2, xAxis ); + MatrixGetColumn( xform, 1, yAxis ); + Circle( position, xAxis, yAxis, radius, r, g, b, a, bNoDepthTest, flDuration ); +} + +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 ) +{ + const unsigned int nSegments = 16; + const float flRadStep = (M_PI*2.0f) / (float) nSegments; + + Vector vecLastPosition; + + // Find our first position + // Retained for triangle fanning + Vector vecStart = position + xAxis * radius; + Vector vecPosition = vecStart; + + // Draw out each segment (fanning triangles if we have an alpha amount) + for ( int i = 1; i <= nSegments; i++ ) + { + // Store off our last position + vecLastPosition = vecPosition; + + // Calculate the new one + float flSin, flCos; + SinCos( flRadStep*i, &flSin, &flCos ); + vecPosition = position + (xAxis * flCos * radius) + (yAxis * flSin * radius); + + // Draw the line + Line( vecLastPosition, vecPosition, r, g, b, bNoDepthTest, flDuration ); + + // If we have an alpha value, then draw the fan + if ( a && i > 1 ) + { + debugoverlay->AddTriangleOverlay( vecStart, vecLastPosition, vecPosition, r, g, b, a, bNoDepthTest, flDuration ); + } + } +} + +void NDebugOverlay::Sphere( const Vector &position, const QAngle &angles, float radius, int r, int g, int b, int a, bool bNoDepthTest, float flDuration ) +{ + // Setup our transform matrix + matrix3x4_t xform; + AngleMatrix( angles, position, xform ); + Vector xAxis, yAxis, zAxis; + // default draws circle in the y/z plane + MatrixGetColumn( xform, 0, xAxis ); + MatrixGetColumn( xform, 1, yAxis ); + MatrixGetColumn( xform, 2, zAxis ); + Circle( position, xAxis, yAxis, radius, r, g, b, a, bNoDepthTest, flDuration ); // xy plane + Circle( position, yAxis, zAxis, radius, r, g, b, a, bNoDepthTest, flDuration ); // yz plane + Circle( position, xAxis, zAxis, radius, r, g, b, a, bNoDepthTest, flDuration ); // xz plane +} -- cgit v1.2.3