diff options
Diffstat (limited to 'game/client/fx_line.cpp')
| -rw-r--r-- | game/client/fx_line.cpp | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/game/client/fx_line.cpp b/game/client/fx_line.cpp new file mode 100644 index 0000000..9e0d349 --- /dev/null +++ b/game/client/fx_line.cpp @@ -0,0 +1,310 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $Workfile: $ +// $Date: $ +// $NoKeywords: $ +//=============================================================================// +#include "cbase.h" +#include "materialsystem/imaterial.h" +#include "clientsideeffects.h" +#include "fx_line.h" +#include "materialsystem/imesh.h" +#include "view.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +/* +================================================== +CFXLine +================================================== +*/ + +CFXLine::CFXLine( const char *name, const FXLineData_t &data ) +: CClientSideEffect( name ) +{ + m_FXData = data; + + m_FXData.m_flLifeTime = 0.0f; + + if ( m_FXData.m_pMaterial != NULL ) + { + m_FXData.m_pMaterial->IncrementReferenceCount(); + } +} + +CFXLine::~CFXLine( void ) +{ + Destroy(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : frametime - +//----------------------------------------------------------------------------- +void CFXLine::Draw( double frametime ) +{ + // Update the effect + Update( frametime ); + + Vector lineDir, viewDir; + + //Get the proper orientation for the line + VectorSubtract( m_FXData.m_vecStart, m_FXData.m_vecEnd, lineDir ); + VectorSubtract( m_FXData.m_vecEnd, CurrentViewOrigin(), viewDir ); + + Vector cross = lineDir.Cross( viewDir ); + + VectorNormalize( cross ); + + CMatRenderContextPtr pRenderContext( materials ); + + //Bind the material + IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_FXData.m_pMaterial ); + + CMeshBuilder meshBuilder; + + Vector tmp; + meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); + + float scaleTimePerc = ( m_FXData.m_flLifeTime / m_FXData.m_flDieTime ); + float scale = m_FXData.m_flStartScale + ( ( m_FXData.m_flEndScale - m_FXData.m_flStartScale ) * scaleTimePerc ); + + color32 color = {255,255,255,255}; + + float alpha = m_FXData.m_flStartAlpha + ( ( m_FXData.m_flEndAlpha - m_FXData.m_flStartAlpha ) * scaleTimePerc ); + alpha = clamp( alpha, 0.0f, 1.0f ); + + color.a *= alpha; + + // Start + VectorMA( m_FXData.m_vecStart, -scale, cross, tmp ); + meshBuilder.Position3fv( tmp.Base() ); + meshBuilder.TexCoord2f( 0, 1.0f, 1.0f ); + meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); + meshBuilder.Normal3fv( cross.Base() ); + meshBuilder.AdvanceVertex(); + + VectorMA( m_FXData.m_vecStart, scale, cross, tmp ); + meshBuilder.Position3fv( tmp.Base() ); + meshBuilder.TexCoord2f( 0, 0.0f, 1.0f ); + meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); + meshBuilder.Normal3fv( cross.Base() ); + meshBuilder.AdvanceVertex(); + + // End + VectorMA( m_FXData.m_vecEnd, scale, cross, tmp ); + meshBuilder.Position3fv( tmp.Base() ); + meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); + meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); + meshBuilder.Normal3fv( cross.Base() ); + meshBuilder.AdvanceVertex(); + + VectorMA( m_FXData.m_vecEnd, -scale, cross, tmp ); + meshBuilder.Position3fv( tmp.Base() ); + meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); + meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); + meshBuilder.Normal3fv( cross.Base() ); + meshBuilder.AdvanceVertex(); + + meshBuilder.End(); + pMesh->Draw(); +} + +//----------------------------------------------------------------------------- +// Purpose: +// Output : Returns true on success, false on failure. +//----------------------------------------------------------------------------- +bool CFXLine::IsActive( void ) +{ + return ( m_FXData.m_flLifeTime < m_FXData.m_flDieTime ) ? true : false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CFXLine::Destroy( void ) +{ + //Release the material + if ( m_FXData.m_pMaterial != NULL ) + { + m_FXData.m_pMaterial->DecrementReferenceCount(); + m_FXData.m_pMaterial = NULL; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : frametime - +//----------------------------------------------------------------------------- +void CFXLine::Update( double frametime ) +{ + m_FXData.m_flLifeTime += frametime; + + //Move our end points + VectorMA( m_FXData.m_vecStart, frametime, m_FXData.m_vecStartVelocity, m_FXData.m_vecStart ); + VectorMA( m_FXData.m_vecEnd, frametime, m_FXData.m_vecEndVelocity, m_FXData.m_vecEnd ); +} + +void FX_DrawLine( const Vector &start, const Vector &end, float scale, IMaterial *pMaterial, const color32 &color ) +{ + Vector lineDir, viewDir; + //Get the proper orientation for the line + VectorSubtract( end, start, lineDir ); + VectorSubtract( end, CurrentViewOrigin(), viewDir ); + + Vector cross = lineDir.Cross( viewDir ); + + VectorNormalize( cross ); + + CMatRenderContextPtr pRenderContext( materials ); + + //Bind the material + IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, pMaterial ); + CMeshBuilder meshBuilder; + + Vector tmp; + meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); + + VectorMA( start, -scale, cross, tmp ); + meshBuilder.Position3fv( tmp.Base() ); + meshBuilder.TexCoord2f( 0, 1.0f, 1.0f ); + meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); + meshBuilder.Normal3fv( cross.Base() ); + meshBuilder.AdvanceVertex(); + + VectorMA( start, scale, cross, tmp ); + meshBuilder.Position3fv( tmp.Base() ); + meshBuilder.TexCoord2f( 0, 0.0f, 1.0f ); + meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); + meshBuilder.Normal3fv( cross.Base() ); + meshBuilder.AdvanceVertex(); + + VectorMA( end, scale, cross, tmp ); + meshBuilder.Position3fv( tmp.Base() ); + meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); + meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); + meshBuilder.Normal3fv( cross.Base() ); + meshBuilder.AdvanceVertex(); + + VectorMA( end, -scale, cross, tmp ); + meshBuilder.Position3fv( tmp.Base() ); + meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); + meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); + meshBuilder.Normal3fv( cross.Base() ); + meshBuilder.AdvanceVertex(); + + meshBuilder.End(); + pMesh->Draw(); +} + + +void FX_DrawLineFade( const Vector &start, const Vector &end, float scale, IMaterial *pMaterial, const color32 &color, float fadeDist ) +{ + Vector lineDir, viewDir; + //Get the proper orientation for the line + VectorSubtract( end, start, lineDir ); + VectorSubtract( end, CurrentViewOrigin(), viewDir ); + + float lineLength = lineDir.Length(); + float t0 = 0.25f; + float t1 = 0.75f; + if ( lineLength > 0 ) + { + t0 = fadeDist / lineLength; + t0 = clamp( t0, 0.0f, 0.25f ); + t1 = 1.0f - t0; + } + + Vector cross = lineDir.Cross( viewDir ); + + VectorNormalize( cross ); + + CMatRenderContextPtr pRenderContext( materials ); + + //Bind the material + IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, pMaterial ); + CMeshBuilder meshBuilder; + + Vector tmp; + meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, 8, 24 ); + + // 2 5 + // 0 1 4 7 + // 3 6 + + // 0,2,1 - 0,1,3 - 7,4,5 - 7,6,4 - 1,4,6, 1,6,3 - 1,5,4 - 1,2,5 + + // v0 + meshBuilder.Position3fv( start.Base() ); + meshBuilder.TexCoord2f( 0, 0.5f, 0.0f ); + meshBuilder.Color4ub( 0, 0, 0, 0 ); + meshBuilder.Normal3fv( cross.Base() ); + meshBuilder.AdvanceVertex(); + // v1 + Vector v1 = start + t0 * lineDir; + meshBuilder.Position3fv( v1.Base() ); + meshBuilder.TexCoord2f( 0, 0.5f, t0 ); + meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); + meshBuilder.Normal3fv( cross.Base() ); + meshBuilder.AdvanceVertex(); + // v2 + tmp = v1 - scale*cross; + meshBuilder.Position3fv( tmp.Base() ); + meshBuilder.TexCoord2f( 0, 1.0f, t0 ); + meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); + meshBuilder.Normal3fv( cross.Base() ); + meshBuilder.AdvanceVertex(); + // v3 + tmp = v1 + scale*cross; + meshBuilder.Position3fv( tmp.Base() ); + meshBuilder.TexCoord2f( 0, 0.0f, t0 ); + meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); + meshBuilder.Normal3fv( cross.Base() ); + meshBuilder.AdvanceVertex(); + // v4 + Vector v4 = start + t1 * lineDir; + meshBuilder.Position3fv( v4.Base() ); + meshBuilder.TexCoord2f( 0, 0.5f, t1 ); + meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); + meshBuilder.Normal3fv( cross.Base() ); + meshBuilder.AdvanceVertex(); + // v5 + tmp = v4 - scale*cross; + meshBuilder.Position3fv( tmp.Base() ); + meshBuilder.TexCoord2f( 0, 1.0f, t1 ); + meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); + meshBuilder.Normal3fv( cross.Base() ); + meshBuilder.AdvanceVertex(); + // v6 + tmp = v4 + scale*cross; + meshBuilder.Position3fv( tmp.Base() ); + meshBuilder.TexCoord2f( 0, 0.0f, t1 ); + meshBuilder.Color4ub( color.r, color.g, color.b, color.a ); + meshBuilder.Normal3fv( cross.Base() ); + meshBuilder.AdvanceVertex(); + // v7 + meshBuilder.Position3fv( end.Base() ); + meshBuilder.TexCoord2f( 0, 0.5f, 1.0f ); + meshBuilder.Color4ub( 0, 0, 0, 0 ); + meshBuilder.Normal3fv( cross.Base() ); + meshBuilder.AdvanceVertex(); + + + // triangles - 0,2,1 - 0,1,3 - 7,4,5 - 7,6,4 - 1,4,6, 1,6,3 - 1,5,4 - 1,2,5 + meshBuilder.FastIndex( 0 ); meshBuilder.FastIndex( 2 ); meshBuilder.FastIndex( 1 ); + meshBuilder.FastIndex( 0 ); meshBuilder.FastIndex( 1 ); meshBuilder.FastIndex( 3 ); + + meshBuilder.FastIndex( 7 ); meshBuilder.FastIndex( 4 ); meshBuilder.FastIndex( 5 ); + meshBuilder.FastIndex( 7 ); meshBuilder.FastIndex( 6 ); meshBuilder.FastIndex( 4 ); + + meshBuilder.FastIndex( 1 ); meshBuilder.FastIndex( 4 ); meshBuilder.FastIndex( 6 ); + meshBuilder.FastIndex( 1 ); meshBuilder.FastIndex( 6 ); meshBuilder.FastIndex( 3 ); + meshBuilder.FastIndex( 1 ); meshBuilder.FastIndex( 5 ); meshBuilder.FastIndex( 4 ); + meshBuilder.FastIndex( 1 ); meshBuilder.FastIndex( 2 ); meshBuilder.FastIndex( 5 ); + + meshBuilder.End(); + pMesh->Draw(); +} |