aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/client/flashlighteffect.cpp
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/client/flashlighteffect.cpp
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/game/client/flashlighteffect.cpp')
-rw-r--r--mp/src/game/client/flashlighteffect.cpp1080
1 files changed, 540 insertions, 540 deletions
diff --git a/mp/src/game/client/flashlighteffect.cpp b/mp/src/game/client/flashlighteffect.cpp
index 671cb9af..6385ad30 100644
--- a/mp/src/game/client/flashlighteffect.cpp
+++ b/mp/src/game/client/flashlighteffect.cpp
@@ -1,540 +1,540 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//===========================================================================//
-
-#include "cbase.h"
-#include "flashlighteffect.h"
-#include "dlight.h"
-#include "iefx.h"
-#include "iviewrender.h"
-#include "view.h"
-#include "engine/ivdebugoverlay.h"
-#include "tier0/vprof.h"
-#include "tier1/KeyValues.h"
-#include "toolframework_client.h"
-
-#ifdef HL2_CLIENT_DLL
-#include "c_basehlplayer.h"
-#endif // HL2_CLIENT_DLL
-
-#if defined( _X360 )
-extern ConVar r_flashlightdepthres;
-#else
-extern ConVar r_flashlightdepthres;
-#endif
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-extern ConVar r_flashlightdepthtexture;
-
-void r_newflashlightCallback_f( IConVar *pConVar, const char *pOldString, float flOldValue );
-
-static ConVar r_newflashlight( "r_newflashlight", "1", FCVAR_CHEAT, "", r_newflashlightCallback_f );
-static ConVar r_swingflashlight( "r_swingflashlight", "1", FCVAR_CHEAT );
-static ConVar r_flashlightlockposition( "r_flashlightlockposition", "0", FCVAR_CHEAT );
-static ConVar r_flashlightfov( "r_flashlightfov", "45.0", FCVAR_CHEAT );
-static ConVar r_flashlightoffsetx( "r_flashlightoffsetx", "10.0", FCVAR_CHEAT );
-static ConVar r_flashlightoffsety( "r_flashlightoffsety", "-20.0", FCVAR_CHEAT );
-static ConVar r_flashlightoffsetz( "r_flashlightoffsetz", "24.0", FCVAR_CHEAT );
-static ConVar r_flashlightnear( "r_flashlightnear", "4.0", FCVAR_CHEAT );
-static ConVar r_flashlightfar( "r_flashlightfar", "750.0", FCVAR_CHEAT );
-static ConVar r_flashlightconstant( "r_flashlightconstant", "0.0", FCVAR_CHEAT );
-static ConVar r_flashlightlinear( "r_flashlightlinear", "100.0", FCVAR_CHEAT );
-static ConVar r_flashlightquadratic( "r_flashlightquadratic", "0.0", FCVAR_CHEAT );
-static ConVar r_flashlightvisualizetrace( "r_flashlightvisualizetrace", "0", FCVAR_CHEAT );
-static ConVar r_flashlightambient( "r_flashlightambient", "0.0", FCVAR_CHEAT );
-static ConVar r_flashlightshadowatten( "r_flashlightshadowatten", "0.35", FCVAR_CHEAT );
-static ConVar r_flashlightladderdist( "r_flashlightladderdist", "40.0", FCVAR_CHEAT );
-static ConVar mat_slopescaledepthbias_shadowmap( "mat_slopescaledepthbias_shadowmap", "16", FCVAR_CHEAT );
-static ConVar mat_depthbias_shadowmap( "mat_depthbias_shadowmap", "0.0005", FCVAR_CHEAT );
-
-
-void r_newflashlightCallback_f( IConVar *pConVar, const char *pOldString, float flOldValue )
-{
- if( engine->GetDXSupportLevel() < 70 )
- {
- r_newflashlight.SetValue( 0 );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : nEntIndex - The m_nEntIndex of the client entity that is creating us.
-// vecPos - The position of the light emitter.
-// vecDir - The direction of the light emission.
-//-----------------------------------------------------------------------------
-CFlashlightEffect::CFlashlightEffect(int nEntIndex)
-{
- m_FlashlightHandle = CLIENTSHADOW_INVALID_HANDLE;
- m_nEntIndex = nEntIndex;
-
- m_bIsOn = false;
- m_pPointLight = NULL;
- if( engine->GetDXSupportLevel() < 70 )
- {
- r_newflashlight.SetValue( 0 );
- }
-
- if ( g_pMaterialSystemHardwareConfig->SupportsBorderColor() )
- {
- m_FlashlightTexture.Init( "effects/flashlight_border", TEXTURE_GROUP_OTHER, true );
- }
- else
- {
- m_FlashlightTexture.Init( "effects/flashlight001", TEXTURE_GROUP_OTHER, true );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-CFlashlightEffect::~CFlashlightEffect()
-{
- LightOff();
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CFlashlightEffect::TurnOn()
-{
- m_bIsOn = true;
- m_flDistMod = 1.0f;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CFlashlightEffect::TurnOff()
-{
- if (m_bIsOn)
- {
- m_bIsOn = false;
- LightOff();
- }
-}
-
-// Custom trace filter that skips the player and the view model.
-// If we don't do this, we'll end up having the light right in front of us all
-// the time.
-class CTraceFilterSkipPlayerAndViewModel : public CTraceFilter
-{
-public:
- virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
- {
- // Test against the vehicle too?
- // FLASHLIGHTFIXME: how do you know that you are actually inside of the vehicle?
- C_BaseEntity *pEntity = EntityFromEntityHandle( pServerEntity );
- if ( !pEntity )
- return true;
-
- if ( ( dynamic_cast<C_BaseViewModel *>( pEntity ) != NULL ) ||
- ( dynamic_cast<C_BasePlayer *>( pEntity ) != NULL ) ||
- pEntity->GetCollisionGroup() == COLLISION_GROUP_DEBRIS ||
- pEntity->GetCollisionGroup() == COLLISION_GROUP_INTERACTIVE_DEBRIS )
- {
- return false;
- }
-
- return true;
- }
-};
-
-//-----------------------------------------------------------------------------
-// Purpose: Do the headlight
-//-----------------------------------------------------------------------------
-void CFlashlightEffect::UpdateLightNew(const Vector &vecPos, const Vector &vecForward, const Vector &vecRight, const Vector &vecUp )
-{
- VPROF_BUDGET( "CFlashlightEffect::UpdateLightNew", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING );
-
- FlashlightState_t state;
-
- // We will lock some of the flashlight params if player is on a ladder, to prevent oscillations due to the trace-rays
- bool bPlayerOnLadder = ( C_BasePlayer::GetLocalPlayer()->GetMoveType() == MOVETYPE_LADDER );
-
- const float flEpsilon = 0.1f; // Offset flashlight position along vecUp
- const float flDistCutoff = 128.0f;
- const float flDistDrag = 0.2;
-
- CTraceFilterSkipPlayerAndViewModel traceFilter;
- float flOffsetY = r_flashlightoffsety.GetFloat();
-
- if( r_swingflashlight.GetBool() )
- {
- // This projects the view direction backwards, attempting to raise the vertical
- // offset of the flashlight, but only when the player is looking down.
- Vector vecSwingLight = vecPos + vecForward * -12.0f;
- if( vecSwingLight.z > vecPos.z )
- {
- flOffsetY += (vecSwingLight.z - vecPos.z);
- }
- }
-
- Vector vOrigin = vecPos + flOffsetY * vecUp;
-
- // Not on ladder...trace a hull
- if ( !bPlayerOnLadder )
- {
- trace_t pmOriginTrace;
- UTIL_TraceHull( vecPos, vOrigin, Vector(-4, -4, -4), Vector(4, 4, 4), MASK_SOLID & ~(CONTENTS_HITBOX), &traceFilter, &pmOriginTrace );
-
- if ( pmOriginTrace.DidHit() )
- {
- vOrigin = vecPos;
- }
- }
- else // on ladder...skip the above hull trace
- {
- vOrigin = vecPos;
- }
-
- // Now do a trace along the flashlight direction to ensure there is nothing within range to pull back from
- int iMask = MASK_OPAQUE_AND_NPCS;
- iMask &= ~CONTENTS_HITBOX;
- iMask |= CONTENTS_WINDOW;
-
- Vector vTarget = vecPos + vecForward * r_flashlightfar.GetFloat();
-
- // Work with these local copies of the basis for the rest of the function
- Vector vDir = vTarget - vOrigin;
- Vector vRight = vecRight;
- Vector vUp = vecUp;
- VectorNormalize( vDir );
- VectorNormalize( vRight );
- VectorNormalize( vUp );
-
- // Orthonormalize the basis, since the flashlight texture projection will require this later...
- vUp -= DotProduct( vDir, vUp ) * vDir;
- VectorNormalize( vUp );
- vRight -= DotProduct( vDir, vRight ) * vDir;
- VectorNormalize( vRight );
- vRight -= DotProduct( vUp, vRight ) * vUp;
- VectorNormalize( vRight );
-
- AssertFloatEquals( DotProduct( vDir, vRight ), 0.0f, 1e-3 );
- AssertFloatEquals( DotProduct( vDir, vUp ), 0.0f, 1e-3 );
- AssertFloatEquals( DotProduct( vRight, vUp ), 0.0f, 1e-3 );
-
- trace_t pmDirectionTrace;
- UTIL_TraceHull( vOrigin, vTarget, Vector( -4, -4, -4 ), Vector( 4, 4, 4 ), iMask, &traceFilter, &pmDirectionTrace );
-
- if ( r_flashlightvisualizetrace.GetBool() == true )
- {
- debugoverlay->AddBoxOverlay( pmDirectionTrace.endpos, Vector( -4, -4, -4 ), Vector( 4, 4, 4 ), QAngle( 0, 0, 0 ), 0, 0, 255, 16, 0 );
- debugoverlay->AddLineOverlay( vOrigin, pmDirectionTrace.endpos, 255, 0, 0, false, 0 );
- }
-
- float flDist = (pmDirectionTrace.endpos - vOrigin).Length();
- if ( flDist < flDistCutoff )
- {
- // We have an intersection with our cutoff range
- // Determine how far to pull back, then trace to see if we are clear
- float flPullBackDist = bPlayerOnLadder ? r_flashlightladderdist.GetFloat() : flDistCutoff - flDist; // Fixed pull-back distance if on ladder
- m_flDistMod = Lerp( flDistDrag, m_flDistMod, flPullBackDist );
-
- if ( !bPlayerOnLadder )
- {
- trace_t pmBackTrace;
- UTIL_TraceHull( vOrigin, vOrigin - vDir*(flPullBackDist-flEpsilon), Vector( -4, -4, -4 ), Vector( 4, 4, 4 ), iMask, &traceFilter, &pmBackTrace );
- if( pmBackTrace.DidHit() )
- {
- // We have an intersection behind us as well, so limit our m_flDistMod
- float flMaxDist = (pmBackTrace.endpos - vOrigin).Length() - flEpsilon;
- if( m_flDistMod > flMaxDist )
- m_flDistMod = flMaxDist;
- }
- }
- }
- else
- {
- m_flDistMod = Lerp( flDistDrag, m_flDistMod, 0.0f );
- }
- vOrigin = vOrigin - vDir * m_flDistMod;
-
- state.m_vecLightOrigin = vOrigin;
-
- BasisToQuaternion( vDir, vRight, vUp, state.m_quatOrientation );
-
- state.m_fQuadraticAtten = r_flashlightquadratic.GetFloat();
-
- bool bFlicker = false;
-
-#ifdef HL2_EPISODIC
- C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
- if ( pPlayer )
- {
- float flBatteryPower = ( pPlayer->m_HL2Local.m_flFlashBattery >= 0.0f ) ? ( pPlayer->m_HL2Local.m_flFlashBattery ) : pPlayer->m_HL2Local.m_flSuitPower;
- if ( flBatteryPower <= 10.0f )
- {
- float flScale;
- if ( flBatteryPower >= 0.0f )
- {
- flScale = ( flBatteryPower <= 4.5f ) ? SimpleSplineRemapVal( flBatteryPower, 4.5f, 0.0f, 1.0f, 0.0f ) : 1.0f;
- }
- else
- {
- flScale = SimpleSplineRemapVal( flBatteryPower, 10.0f, 4.8f, 1.0f, 0.0f );
- }
-
- flScale = clamp( flScale, 0.0f, 1.0f );
-
- if ( flScale < 0.35f )
- {
- float flFlicker = cosf( gpGlobals->curtime * 6.0f ) * sinf( gpGlobals->curtime * 15.0f );
-
- if ( flFlicker > 0.25f && flFlicker < 0.75f )
- {
- // On
- state.m_fLinearAtten = r_flashlightlinear.GetFloat() * flScale;
- }
- else
- {
- // Off
- state.m_fLinearAtten = 0.0f;
- }
- }
- else
- {
- float flNoise = cosf( gpGlobals->curtime * 7.0f ) * sinf( gpGlobals->curtime * 25.0f );
- state.m_fLinearAtten = r_flashlightlinear.GetFloat() * flScale + 1.5f * flNoise;
- }
-
- state.m_fHorizontalFOVDegrees = r_flashlightfov.GetFloat() - ( 16.0f * (1.0f-flScale) );
- state.m_fVerticalFOVDegrees = r_flashlightfov.GetFloat() - ( 16.0f * (1.0f-flScale) );
-
- bFlicker = true;
- }
- }
-#endif // HL2_EPISODIC
-
- if ( bFlicker == false )
- {
- state.m_fLinearAtten = r_flashlightlinear.GetFloat();
- state.m_fHorizontalFOVDegrees = r_flashlightfov.GetFloat();
- state.m_fVerticalFOVDegrees = r_flashlightfov.GetFloat();
- }
-
- state.m_fConstantAtten = r_flashlightconstant.GetFloat();
- state.m_Color[0] = 1.0f;
- state.m_Color[1] = 1.0f;
- state.m_Color[2] = 1.0f;
- state.m_Color[3] = r_flashlightambient.GetFloat();
- state.m_NearZ = r_flashlightnear.GetFloat() + m_flDistMod; // Push near plane out so that we don't clip the world when the flashlight pulls back
- state.m_FarZ = r_flashlightfar.GetFloat();
- state.m_bEnableShadows = r_flashlightdepthtexture.GetBool();
- state.m_flShadowMapResolution = r_flashlightdepthres.GetInt();
-
- state.m_pSpotlightTexture = m_FlashlightTexture;
- state.m_nSpotlightTextureFrame = 0;
-
- state.m_flShadowAtten = r_flashlightshadowatten.GetFloat();
- state.m_flShadowSlopeScaleDepthBias = mat_slopescaledepthbias_shadowmap.GetFloat();
- state.m_flShadowDepthBias = mat_depthbias_shadowmap.GetFloat();
-
- if( m_FlashlightHandle == CLIENTSHADOW_INVALID_HANDLE )
- {
- m_FlashlightHandle = g_pClientShadowMgr->CreateFlashlight( state );
- }
- else
- {
- if( !r_flashlightlockposition.GetBool() )
- {
- g_pClientShadowMgr->UpdateFlashlightState( m_FlashlightHandle, state );
- }
- }
-
- g_pClientShadowMgr->UpdateProjectedTexture( m_FlashlightHandle, true );
-
- // Kill the old flashlight method if we have one.
- LightOffOld();
-
-#ifndef NO_TOOLFRAMEWORK
- if ( clienttools->IsInRecordingMode() )
- {
- KeyValues *msg = new KeyValues( "FlashlightState" );
- msg->SetFloat( "time", gpGlobals->curtime );
- msg->SetInt( "entindex", m_nEntIndex );
- msg->SetInt( "flashlightHandle", m_FlashlightHandle );
- msg->SetPtr( "flashlightState", &state );
- ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
- msg->deleteThis();
- }
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Do the headlight
-//-----------------------------------------------------------------------------
-void CFlashlightEffect::UpdateLightOld(const Vector &vecPos, const Vector &vecDir, int nDistance)
-{
- if ( !m_pPointLight || ( m_pPointLight->key != m_nEntIndex ))
- {
- // Set up the environment light
- m_pPointLight = effects->CL_AllocDlight(m_nEntIndex);
- m_pPointLight->flags = 0.0f;
- m_pPointLight->radius = 80;
- }
-
- // For bumped lighting
- VectorCopy(vecDir, m_pPointLight->m_Direction);
-
- Vector end;
- end = vecPos + nDistance * vecDir;
-
- // Trace a line outward, skipping the player model and the view model.
- trace_t pm;
- CTraceFilterSkipPlayerAndViewModel traceFilter;
- UTIL_TraceLine( vecPos, end, MASK_ALL, &traceFilter, &pm );
- VectorCopy( pm.endpos, m_pPointLight->origin );
-
- float falloff = pm.fraction * nDistance;
-
- if ( falloff < 500 )
- falloff = 1.0;
- else
- falloff = 500.0 / falloff;
-
- falloff *= falloff;
-
- m_pPointLight->radius = 80;
- m_pPointLight->color.r = m_pPointLight->color.g = m_pPointLight->color.b = 255 * falloff;
- m_pPointLight->color.exponent = 0;
-
- // Make it live for a bit
- m_pPointLight->die = gpGlobals->curtime + 0.2f;
-
- // Update list of surfaces we influence
- render->TouchLight( m_pPointLight );
-
- // kill the new flashlight if we have one
- LightOffNew();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Do the headlight
-//-----------------------------------------------------------------------------
-void CFlashlightEffect::UpdateLight(const Vector &vecPos, const Vector &vecDir, const Vector &vecRight, const Vector &vecUp, int nDistance)
-{
- if ( !m_bIsOn )
- {
- return;
- }
- if( r_newflashlight.GetBool() )
- {
- UpdateLightNew( vecPos, vecDir, vecRight, vecUp );
- }
- else
- {
- UpdateLightOld( vecPos, vecDir, nDistance );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CFlashlightEffect::LightOffNew()
-{
-#ifndef NO_TOOLFRAMEWORK
- if ( clienttools->IsInRecordingMode() )
- {
- KeyValues *msg = new KeyValues( "FlashlightState" );
- msg->SetFloat( "time", gpGlobals->curtime );
- msg->SetInt( "entindex", m_nEntIndex );
- msg->SetInt( "flashlightHandle", m_FlashlightHandle );
- msg->SetPtr( "flashlightState", NULL );
- ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
- msg->deleteThis();
- }
-#endif
-
- // Clear out the light
- if( m_FlashlightHandle != CLIENTSHADOW_INVALID_HANDLE )
- {
- g_pClientShadowMgr->DestroyFlashlight( m_FlashlightHandle );
- m_FlashlightHandle = CLIENTSHADOW_INVALID_HANDLE;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CFlashlightEffect::LightOffOld()
-{
- if ( m_pPointLight && ( m_pPointLight->key == m_nEntIndex ) )
- {
- m_pPointLight->die = gpGlobals->curtime;
- m_pPointLight = NULL;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CFlashlightEffect::LightOff()
-{
- LightOffOld();
- LightOffNew();
-}
-
-CHeadlightEffect::CHeadlightEffect()
-{
-
-}
-
-CHeadlightEffect::~CHeadlightEffect()
-{
-
-}
-
-void CHeadlightEffect::UpdateLight( const Vector &vecPos, const Vector &vecDir, const Vector &vecRight, const Vector &vecUp, int nDistance )
-{
- if ( IsOn() == false )
- return;
-
- FlashlightState_t state;
- Vector basisX, basisY, basisZ;
- basisX = vecDir;
- basisY = vecRight;
- basisZ = vecUp;
- VectorNormalize(basisX);
- VectorNormalize(basisY);
- VectorNormalize(basisZ);
-
- BasisToQuaternion( basisX, basisY, basisZ, state.m_quatOrientation );
-
- state.m_vecLightOrigin = vecPos;
-
- state.m_fHorizontalFOVDegrees = 45.0f;
- state.m_fVerticalFOVDegrees = 30.0f;
- state.m_fQuadraticAtten = r_flashlightquadratic.GetFloat();
- state.m_fLinearAtten = r_flashlightlinear.GetFloat();
- state.m_fConstantAtten = r_flashlightconstant.GetFloat();
- state.m_Color[0] = 1.0f;
- state.m_Color[1] = 1.0f;
- state.m_Color[2] = 1.0f;
- state.m_Color[3] = r_flashlightambient.GetFloat();
- state.m_NearZ = r_flashlightnear.GetFloat();
- state.m_FarZ = r_flashlightfar.GetFloat();
- state.m_bEnableShadows = true;
- state.m_pSpotlightTexture = m_FlashlightTexture;
- state.m_nSpotlightTextureFrame = 0;
-
- if( GetFlashlightHandle() == CLIENTSHADOW_INVALID_HANDLE )
- {
- SetFlashlightHandle( g_pClientShadowMgr->CreateFlashlight( state ) );
- }
- else
- {
- g_pClientShadowMgr->UpdateFlashlightState( GetFlashlightHandle(), state );
- }
-
- g_pClientShadowMgr->UpdateProjectedTexture( GetFlashlightHandle(), true );
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//===========================================================================//
+
+#include "cbase.h"
+#include "flashlighteffect.h"
+#include "dlight.h"
+#include "iefx.h"
+#include "iviewrender.h"
+#include "view.h"
+#include "engine/ivdebugoverlay.h"
+#include "tier0/vprof.h"
+#include "tier1/KeyValues.h"
+#include "toolframework_client.h"
+
+#ifdef HL2_CLIENT_DLL
+#include "c_basehlplayer.h"
+#endif // HL2_CLIENT_DLL
+
+#if defined( _X360 )
+extern ConVar r_flashlightdepthres;
+#else
+extern ConVar r_flashlightdepthres;
+#endif
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+extern ConVar r_flashlightdepthtexture;
+
+void r_newflashlightCallback_f( IConVar *pConVar, const char *pOldString, float flOldValue );
+
+static ConVar r_newflashlight( "r_newflashlight", "1", FCVAR_CHEAT, "", r_newflashlightCallback_f );
+static ConVar r_swingflashlight( "r_swingflashlight", "1", FCVAR_CHEAT );
+static ConVar r_flashlightlockposition( "r_flashlightlockposition", "0", FCVAR_CHEAT );
+static ConVar r_flashlightfov( "r_flashlightfov", "45.0", FCVAR_CHEAT );
+static ConVar r_flashlightoffsetx( "r_flashlightoffsetx", "10.0", FCVAR_CHEAT );
+static ConVar r_flashlightoffsety( "r_flashlightoffsety", "-20.0", FCVAR_CHEAT );
+static ConVar r_flashlightoffsetz( "r_flashlightoffsetz", "24.0", FCVAR_CHEAT );
+static ConVar r_flashlightnear( "r_flashlightnear", "4.0", FCVAR_CHEAT );
+static ConVar r_flashlightfar( "r_flashlightfar", "750.0", FCVAR_CHEAT );
+static ConVar r_flashlightconstant( "r_flashlightconstant", "0.0", FCVAR_CHEAT );
+static ConVar r_flashlightlinear( "r_flashlightlinear", "100.0", FCVAR_CHEAT );
+static ConVar r_flashlightquadratic( "r_flashlightquadratic", "0.0", FCVAR_CHEAT );
+static ConVar r_flashlightvisualizetrace( "r_flashlightvisualizetrace", "0", FCVAR_CHEAT );
+static ConVar r_flashlightambient( "r_flashlightambient", "0.0", FCVAR_CHEAT );
+static ConVar r_flashlightshadowatten( "r_flashlightshadowatten", "0.35", FCVAR_CHEAT );
+static ConVar r_flashlightladderdist( "r_flashlightladderdist", "40.0", FCVAR_CHEAT );
+static ConVar mat_slopescaledepthbias_shadowmap( "mat_slopescaledepthbias_shadowmap", "16", FCVAR_CHEAT );
+static ConVar mat_depthbias_shadowmap( "mat_depthbias_shadowmap", "0.0005", FCVAR_CHEAT );
+
+
+void r_newflashlightCallback_f( IConVar *pConVar, const char *pOldString, float flOldValue )
+{
+ if( engine->GetDXSupportLevel() < 70 )
+ {
+ r_newflashlight.SetValue( 0 );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : nEntIndex - The m_nEntIndex of the client entity that is creating us.
+// vecPos - The position of the light emitter.
+// vecDir - The direction of the light emission.
+//-----------------------------------------------------------------------------
+CFlashlightEffect::CFlashlightEffect(int nEntIndex)
+{
+ m_FlashlightHandle = CLIENTSHADOW_INVALID_HANDLE;
+ m_nEntIndex = nEntIndex;
+
+ m_bIsOn = false;
+ m_pPointLight = NULL;
+ if( engine->GetDXSupportLevel() < 70 )
+ {
+ r_newflashlight.SetValue( 0 );
+ }
+
+ if ( g_pMaterialSystemHardwareConfig->SupportsBorderColor() )
+ {
+ m_FlashlightTexture.Init( "effects/flashlight_border", TEXTURE_GROUP_OTHER, true );
+ }
+ else
+ {
+ m_FlashlightTexture.Init( "effects/flashlight001", TEXTURE_GROUP_OTHER, true );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CFlashlightEffect::~CFlashlightEffect()
+{
+ LightOff();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CFlashlightEffect::TurnOn()
+{
+ m_bIsOn = true;
+ m_flDistMod = 1.0f;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CFlashlightEffect::TurnOff()
+{
+ if (m_bIsOn)
+ {
+ m_bIsOn = false;
+ LightOff();
+ }
+}
+
+// Custom trace filter that skips the player and the view model.
+// If we don't do this, we'll end up having the light right in front of us all
+// the time.
+class CTraceFilterSkipPlayerAndViewModel : public CTraceFilter
+{
+public:
+ virtual bool ShouldHitEntity( IHandleEntity *pServerEntity, int contentsMask )
+ {
+ // Test against the vehicle too?
+ // FLASHLIGHTFIXME: how do you know that you are actually inside of the vehicle?
+ C_BaseEntity *pEntity = EntityFromEntityHandle( pServerEntity );
+ if ( !pEntity )
+ return true;
+
+ if ( ( dynamic_cast<C_BaseViewModel *>( pEntity ) != NULL ) ||
+ ( dynamic_cast<C_BasePlayer *>( pEntity ) != NULL ) ||
+ pEntity->GetCollisionGroup() == COLLISION_GROUP_DEBRIS ||
+ pEntity->GetCollisionGroup() == COLLISION_GROUP_INTERACTIVE_DEBRIS )
+ {
+ return false;
+ }
+
+ return true;
+ }
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: Do the headlight
+//-----------------------------------------------------------------------------
+void CFlashlightEffect::UpdateLightNew(const Vector &vecPos, const Vector &vecForward, const Vector &vecRight, const Vector &vecUp )
+{
+ VPROF_BUDGET( "CFlashlightEffect::UpdateLightNew", VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING );
+
+ FlashlightState_t state;
+
+ // We will lock some of the flashlight params if player is on a ladder, to prevent oscillations due to the trace-rays
+ bool bPlayerOnLadder = ( C_BasePlayer::GetLocalPlayer()->GetMoveType() == MOVETYPE_LADDER );
+
+ const float flEpsilon = 0.1f; // Offset flashlight position along vecUp
+ const float flDistCutoff = 128.0f;
+ const float flDistDrag = 0.2;
+
+ CTraceFilterSkipPlayerAndViewModel traceFilter;
+ float flOffsetY = r_flashlightoffsety.GetFloat();
+
+ if( r_swingflashlight.GetBool() )
+ {
+ // This projects the view direction backwards, attempting to raise the vertical
+ // offset of the flashlight, but only when the player is looking down.
+ Vector vecSwingLight = vecPos + vecForward * -12.0f;
+ if( vecSwingLight.z > vecPos.z )
+ {
+ flOffsetY += (vecSwingLight.z - vecPos.z);
+ }
+ }
+
+ Vector vOrigin = vecPos + flOffsetY * vecUp;
+
+ // Not on ladder...trace a hull
+ if ( !bPlayerOnLadder )
+ {
+ trace_t pmOriginTrace;
+ UTIL_TraceHull( vecPos, vOrigin, Vector(-4, -4, -4), Vector(4, 4, 4), MASK_SOLID & ~(CONTENTS_HITBOX), &traceFilter, &pmOriginTrace );
+
+ if ( pmOriginTrace.DidHit() )
+ {
+ vOrigin = vecPos;
+ }
+ }
+ else // on ladder...skip the above hull trace
+ {
+ vOrigin = vecPos;
+ }
+
+ // Now do a trace along the flashlight direction to ensure there is nothing within range to pull back from
+ int iMask = MASK_OPAQUE_AND_NPCS;
+ iMask &= ~CONTENTS_HITBOX;
+ iMask |= CONTENTS_WINDOW;
+
+ Vector vTarget = vecPos + vecForward * r_flashlightfar.GetFloat();
+
+ // Work with these local copies of the basis for the rest of the function
+ Vector vDir = vTarget - vOrigin;
+ Vector vRight = vecRight;
+ Vector vUp = vecUp;
+ VectorNormalize( vDir );
+ VectorNormalize( vRight );
+ VectorNormalize( vUp );
+
+ // Orthonormalize the basis, since the flashlight texture projection will require this later...
+ vUp -= DotProduct( vDir, vUp ) * vDir;
+ VectorNormalize( vUp );
+ vRight -= DotProduct( vDir, vRight ) * vDir;
+ VectorNormalize( vRight );
+ vRight -= DotProduct( vUp, vRight ) * vUp;
+ VectorNormalize( vRight );
+
+ AssertFloatEquals( DotProduct( vDir, vRight ), 0.0f, 1e-3 );
+ AssertFloatEquals( DotProduct( vDir, vUp ), 0.0f, 1e-3 );
+ AssertFloatEquals( DotProduct( vRight, vUp ), 0.0f, 1e-3 );
+
+ trace_t pmDirectionTrace;
+ UTIL_TraceHull( vOrigin, vTarget, Vector( -4, -4, -4 ), Vector( 4, 4, 4 ), iMask, &traceFilter, &pmDirectionTrace );
+
+ if ( r_flashlightvisualizetrace.GetBool() == true )
+ {
+ debugoverlay->AddBoxOverlay( pmDirectionTrace.endpos, Vector( -4, -4, -4 ), Vector( 4, 4, 4 ), QAngle( 0, 0, 0 ), 0, 0, 255, 16, 0 );
+ debugoverlay->AddLineOverlay( vOrigin, pmDirectionTrace.endpos, 255, 0, 0, false, 0 );
+ }
+
+ float flDist = (pmDirectionTrace.endpos - vOrigin).Length();
+ if ( flDist < flDistCutoff )
+ {
+ // We have an intersection with our cutoff range
+ // Determine how far to pull back, then trace to see if we are clear
+ float flPullBackDist = bPlayerOnLadder ? r_flashlightladderdist.GetFloat() : flDistCutoff - flDist; // Fixed pull-back distance if on ladder
+ m_flDistMod = Lerp( flDistDrag, m_flDistMod, flPullBackDist );
+
+ if ( !bPlayerOnLadder )
+ {
+ trace_t pmBackTrace;
+ UTIL_TraceHull( vOrigin, vOrigin - vDir*(flPullBackDist-flEpsilon), Vector( -4, -4, -4 ), Vector( 4, 4, 4 ), iMask, &traceFilter, &pmBackTrace );
+ if( pmBackTrace.DidHit() )
+ {
+ // We have an intersection behind us as well, so limit our m_flDistMod
+ float flMaxDist = (pmBackTrace.endpos - vOrigin).Length() - flEpsilon;
+ if( m_flDistMod > flMaxDist )
+ m_flDistMod = flMaxDist;
+ }
+ }
+ }
+ else
+ {
+ m_flDistMod = Lerp( flDistDrag, m_flDistMod, 0.0f );
+ }
+ vOrigin = vOrigin - vDir * m_flDistMod;
+
+ state.m_vecLightOrigin = vOrigin;
+
+ BasisToQuaternion( vDir, vRight, vUp, state.m_quatOrientation );
+
+ state.m_fQuadraticAtten = r_flashlightquadratic.GetFloat();
+
+ bool bFlicker = false;
+
+#ifdef HL2_EPISODIC
+ C_BaseHLPlayer *pPlayer = (C_BaseHLPlayer *)C_BasePlayer::GetLocalPlayer();
+ if ( pPlayer )
+ {
+ float flBatteryPower = ( pPlayer->m_HL2Local.m_flFlashBattery >= 0.0f ) ? ( pPlayer->m_HL2Local.m_flFlashBattery ) : pPlayer->m_HL2Local.m_flSuitPower;
+ if ( flBatteryPower <= 10.0f )
+ {
+ float flScale;
+ if ( flBatteryPower >= 0.0f )
+ {
+ flScale = ( flBatteryPower <= 4.5f ) ? SimpleSplineRemapVal( flBatteryPower, 4.5f, 0.0f, 1.0f, 0.0f ) : 1.0f;
+ }
+ else
+ {
+ flScale = SimpleSplineRemapVal( flBatteryPower, 10.0f, 4.8f, 1.0f, 0.0f );
+ }
+
+ flScale = clamp( flScale, 0.0f, 1.0f );
+
+ if ( flScale < 0.35f )
+ {
+ float flFlicker = cosf( gpGlobals->curtime * 6.0f ) * sinf( gpGlobals->curtime * 15.0f );
+
+ if ( flFlicker > 0.25f && flFlicker < 0.75f )
+ {
+ // On
+ state.m_fLinearAtten = r_flashlightlinear.GetFloat() * flScale;
+ }
+ else
+ {
+ // Off
+ state.m_fLinearAtten = 0.0f;
+ }
+ }
+ else
+ {
+ float flNoise = cosf( gpGlobals->curtime * 7.0f ) * sinf( gpGlobals->curtime * 25.0f );
+ state.m_fLinearAtten = r_flashlightlinear.GetFloat() * flScale + 1.5f * flNoise;
+ }
+
+ state.m_fHorizontalFOVDegrees = r_flashlightfov.GetFloat() - ( 16.0f * (1.0f-flScale) );
+ state.m_fVerticalFOVDegrees = r_flashlightfov.GetFloat() - ( 16.0f * (1.0f-flScale) );
+
+ bFlicker = true;
+ }
+ }
+#endif // HL2_EPISODIC
+
+ if ( bFlicker == false )
+ {
+ state.m_fLinearAtten = r_flashlightlinear.GetFloat();
+ state.m_fHorizontalFOVDegrees = r_flashlightfov.GetFloat();
+ state.m_fVerticalFOVDegrees = r_flashlightfov.GetFloat();
+ }
+
+ state.m_fConstantAtten = r_flashlightconstant.GetFloat();
+ state.m_Color[0] = 1.0f;
+ state.m_Color[1] = 1.0f;
+ state.m_Color[2] = 1.0f;
+ state.m_Color[3] = r_flashlightambient.GetFloat();
+ state.m_NearZ = r_flashlightnear.GetFloat() + m_flDistMod; // Push near plane out so that we don't clip the world when the flashlight pulls back
+ state.m_FarZ = r_flashlightfar.GetFloat();
+ state.m_bEnableShadows = r_flashlightdepthtexture.GetBool();
+ state.m_flShadowMapResolution = r_flashlightdepthres.GetInt();
+
+ state.m_pSpotlightTexture = m_FlashlightTexture;
+ state.m_nSpotlightTextureFrame = 0;
+
+ state.m_flShadowAtten = r_flashlightshadowatten.GetFloat();
+ state.m_flShadowSlopeScaleDepthBias = mat_slopescaledepthbias_shadowmap.GetFloat();
+ state.m_flShadowDepthBias = mat_depthbias_shadowmap.GetFloat();
+
+ if( m_FlashlightHandle == CLIENTSHADOW_INVALID_HANDLE )
+ {
+ m_FlashlightHandle = g_pClientShadowMgr->CreateFlashlight( state );
+ }
+ else
+ {
+ if( !r_flashlightlockposition.GetBool() )
+ {
+ g_pClientShadowMgr->UpdateFlashlightState( m_FlashlightHandle, state );
+ }
+ }
+
+ g_pClientShadowMgr->UpdateProjectedTexture( m_FlashlightHandle, true );
+
+ // Kill the old flashlight method if we have one.
+ LightOffOld();
+
+#ifndef NO_TOOLFRAMEWORK
+ if ( clienttools->IsInRecordingMode() )
+ {
+ KeyValues *msg = new KeyValues( "FlashlightState" );
+ msg->SetFloat( "time", gpGlobals->curtime );
+ msg->SetInt( "entindex", m_nEntIndex );
+ msg->SetInt( "flashlightHandle", m_FlashlightHandle );
+ msg->SetPtr( "flashlightState", &state );
+ ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
+ msg->deleteThis();
+ }
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Do the headlight
+//-----------------------------------------------------------------------------
+void CFlashlightEffect::UpdateLightOld(const Vector &vecPos, const Vector &vecDir, int nDistance)
+{
+ if ( !m_pPointLight || ( m_pPointLight->key != m_nEntIndex ))
+ {
+ // Set up the environment light
+ m_pPointLight = effects->CL_AllocDlight(m_nEntIndex);
+ m_pPointLight->flags = 0.0f;
+ m_pPointLight->radius = 80;
+ }
+
+ // For bumped lighting
+ VectorCopy(vecDir, m_pPointLight->m_Direction);
+
+ Vector end;
+ end = vecPos + nDistance * vecDir;
+
+ // Trace a line outward, skipping the player model and the view model.
+ trace_t pm;
+ CTraceFilterSkipPlayerAndViewModel traceFilter;
+ UTIL_TraceLine( vecPos, end, MASK_ALL, &traceFilter, &pm );
+ VectorCopy( pm.endpos, m_pPointLight->origin );
+
+ float falloff = pm.fraction * nDistance;
+
+ if ( falloff < 500 )
+ falloff = 1.0;
+ else
+ falloff = 500.0 / falloff;
+
+ falloff *= falloff;
+
+ m_pPointLight->radius = 80;
+ m_pPointLight->color.r = m_pPointLight->color.g = m_pPointLight->color.b = 255 * falloff;
+ m_pPointLight->color.exponent = 0;
+
+ // Make it live for a bit
+ m_pPointLight->die = gpGlobals->curtime + 0.2f;
+
+ // Update list of surfaces we influence
+ render->TouchLight( m_pPointLight );
+
+ // kill the new flashlight if we have one
+ LightOffNew();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Do the headlight
+//-----------------------------------------------------------------------------
+void CFlashlightEffect::UpdateLight(const Vector &vecPos, const Vector &vecDir, const Vector &vecRight, const Vector &vecUp, int nDistance)
+{
+ if ( !m_bIsOn )
+ {
+ return;
+ }
+ if( r_newflashlight.GetBool() )
+ {
+ UpdateLightNew( vecPos, vecDir, vecRight, vecUp );
+ }
+ else
+ {
+ UpdateLightOld( vecPos, vecDir, nDistance );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CFlashlightEffect::LightOffNew()
+{
+#ifndef NO_TOOLFRAMEWORK
+ if ( clienttools->IsInRecordingMode() )
+ {
+ KeyValues *msg = new KeyValues( "FlashlightState" );
+ msg->SetFloat( "time", gpGlobals->curtime );
+ msg->SetInt( "entindex", m_nEntIndex );
+ msg->SetInt( "flashlightHandle", m_FlashlightHandle );
+ msg->SetPtr( "flashlightState", NULL );
+ ToolFramework_PostToolMessage( HTOOLHANDLE_INVALID, msg );
+ msg->deleteThis();
+ }
+#endif
+
+ // Clear out the light
+ if( m_FlashlightHandle != CLIENTSHADOW_INVALID_HANDLE )
+ {
+ g_pClientShadowMgr->DestroyFlashlight( m_FlashlightHandle );
+ m_FlashlightHandle = CLIENTSHADOW_INVALID_HANDLE;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CFlashlightEffect::LightOffOld()
+{
+ if ( m_pPointLight && ( m_pPointLight->key == m_nEntIndex ) )
+ {
+ m_pPointLight->die = gpGlobals->curtime;
+ m_pPointLight = NULL;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CFlashlightEffect::LightOff()
+{
+ LightOffOld();
+ LightOffNew();
+}
+
+CHeadlightEffect::CHeadlightEffect()
+{
+
+}
+
+CHeadlightEffect::~CHeadlightEffect()
+{
+
+}
+
+void CHeadlightEffect::UpdateLight( const Vector &vecPos, const Vector &vecDir, const Vector &vecRight, const Vector &vecUp, int nDistance )
+{
+ if ( IsOn() == false )
+ return;
+
+ FlashlightState_t state;
+ Vector basisX, basisY, basisZ;
+ basisX = vecDir;
+ basisY = vecRight;
+ basisZ = vecUp;
+ VectorNormalize(basisX);
+ VectorNormalize(basisY);
+ VectorNormalize(basisZ);
+
+ BasisToQuaternion( basisX, basisY, basisZ, state.m_quatOrientation );
+
+ state.m_vecLightOrigin = vecPos;
+
+ state.m_fHorizontalFOVDegrees = 45.0f;
+ state.m_fVerticalFOVDegrees = 30.0f;
+ state.m_fQuadraticAtten = r_flashlightquadratic.GetFloat();
+ state.m_fLinearAtten = r_flashlightlinear.GetFloat();
+ state.m_fConstantAtten = r_flashlightconstant.GetFloat();
+ state.m_Color[0] = 1.0f;
+ state.m_Color[1] = 1.0f;
+ state.m_Color[2] = 1.0f;
+ state.m_Color[3] = r_flashlightambient.GetFloat();
+ state.m_NearZ = r_flashlightnear.GetFloat();
+ state.m_FarZ = r_flashlightfar.GetFloat();
+ state.m_bEnableShadows = true;
+ state.m_pSpotlightTexture = m_FlashlightTexture;
+ state.m_nSpotlightTextureFrame = 0;
+
+ if( GetFlashlightHandle() == CLIENTSHADOW_INVALID_HANDLE )
+ {
+ SetFlashlightHandle( g_pClientShadowMgr->CreateFlashlight( state ) );
+ }
+ else
+ {
+ g_pClientShadowMgr->UpdateFlashlightState( GetFlashlightHandle(), state );
+ }
+
+ g_pClientShadowMgr->UpdateProjectedTexture( GetFlashlightHandle(), true );
+}
+