|
|
//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================//
#include "cbase.h"
#include "fx_discreetline.h"
#include "materialsystem/imaterial.h"
#include "materialsystem/imesh.h"
#include "view.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
/*
================================================== CFXLine ================================================== */
CFXDiscreetLine::CFXDiscreetLine( const char *name, const Vector& start, const Vector& direction, float velocity, float length, float clipLength, float scale, float life, const char *shader ) : CClientSideEffect( name ) { assert( materials ); if ( materials == NULL ) return;
// Create a material...
m_pMaterial = materials->FindMaterial( shader, TEXTURE_GROUP_CLIENT_EFFECTS ); m_pMaterial->IncrementReferenceCount();
m_vecOrigin = start; m_vecDirection = direction; m_fVelocity = velocity; m_fClipLength = clipLength; m_fScale = scale; m_fLife = life; m_fStartTime = 0.0f; m_fLength = length; }
CFXDiscreetLine::~CFXDiscreetLine( void ) { Destroy(); }
// Does extra calculations to make them more visible over distance
ConVar tracer_extra( "tracer_extra", "1" );
/*
================================================== Draw ================================================== */
void CFXDiscreetLine::Draw( double frametime ) { Vector lineDir, viewDir, cross;
Vector vecEnd, vecStart; Vector tmp;
// Update the effect
Update( frametime );
// Calculate our distance along our path
float sDistance = m_fVelocity * m_fStartTime; float eDistance = sDistance - m_fLength; //Clip to start
sDistance = MAX( 0.0f, sDistance ); eDistance = MAX( 0.0f, eDistance );
if ( ( sDistance == 0.0f ) && ( eDistance == 0.0f ) ) return;
// Clip it
if ( m_fClipLength != 0.0f ) { sDistance = MIN( sDistance, m_fClipLength ); eDistance = MIN( eDistance, m_fClipLength ); }
// Get our delta to calculate the tc offset
float dDistance = fabs( sDistance - eDistance ); float dTotal = ( m_fLength != 0.0f ) ? m_fLength : 0.01f; float fOffset = ( dDistance / dTotal );
// Find our points along our path
VectorMA( m_vecOrigin, sDistance, m_vecDirection, vecEnd ); VectorMA( m_vecOrigin, eDistance, m_vecDirection, vecStart );
//Setup our info for drawing the line
VectorSubtract( vecEnd, vecStart, lineDir ); VectorSubtract( vecEnd, CurrentViewOrigin(), viewDir ); cross = lineDir.Cross( viewDir ); VectorNormalize( cross );
CMeshBuilder meshBuilder; IMesh *pMesh;
CMatRenderContextPtr pRenderContext( materials ); // Better, more visible tracers
if ( tracer_extra.GetBool() ) { float flScreenWidth = ScreenWidth(); float flHalfScreenWidth = flScreenWidth * 0.5f; float zCoord = CurrentViewForward().Dot( vecStart - CurrentViewOrigin() ); float flScreenSpaceWidth = m_fScale * flHalfScreenWidth / zCoord;
float flAlpha; float flScale;
if ( flScreenSpaceWidth < 0.5f ) { flAlpha = RemapVal( flScreenSpaceWidth, 0.25f, 2.0f, 0.3f, 1.0f ); flAlpha = clamp( flAlpha, 0.25f, 1.0f ); flScale = 0.5f * zCoord / flHalfScreenWidth; } else { flAlpha = 1.0f; flScale = m_fScale; }
//Bind the material
pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_pMaterial );
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 2 );
float color = (int) 255.0f * flAlpha;
//FIXME: for now no coloration
VectorMA( vecStart, -flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex();
VectorMA( vecStart, flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex();
VectorMA( vecEnd, flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, fOffset ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex();
VectorMA( vecEnd, -flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, fOffset ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex();
flScale = flScale * 2.0f; color = (int) 64.0f * flAlpha;
// Soft outline
VectorMA( vecStart, -flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex();
VectorMA( vecStart, flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex();
VectorMA( vecEnd, flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, fOffset ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex();
VectorMA( vecEnd, -flScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, fOffset ); meshBuilder.Color4ub( color, color, color, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); } else { //Bind the material
pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, m_pMaterial );
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
//FIXME: for now no coloration
VectorMA( vecStart, -m_fScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex();
VectorMA( vecStart, m_fScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex();
VectorMA( vecEnd, m_fScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 0.0f, fOffset ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex();
VectorMA( vecEnd, -m_fScale, cross, tmp ); meshBuilder.Position3fv( tmp.Base() ); meshBuilder.TexCoord2f( 0, 1.0f, fOffset ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.Normal3fv( cross.Base() ); meshBuilder.AdvanceVertex(); }
meshBuilder.End(); pMesh->Draw(); }
/*
================================================== IsActive ================================================== */
bool CFXDiscreetLine::IsActive( void ) { return ( m_fLife > 0.0 ) ? true : false; }
/*
================================================== Destroy ================================================== */
void CFXDiscreetLine::Destroy( void ) { //Release the material
if ( m_pMaterial != NULL ) { m_pMaterial->DecrementReferenceCount(); m_pMaterial = NULL; } }
/*
================================================== Update ================================================== */
void CFXDiscreetLine::Update( double frametime ) { m_fStartTime += frametime; m_fLife -= frametime;
//Move our end points
//VectorMA( m_vecStart, frametime, m_vecStartVelocity, m_vecStart );
//VectorMA( m_vecEnd, frametime, m_vecStartVelocity, m_vecEnd );
}
|