Files
Fake-CSM-Mapbase/client/c_env_cascade_light.cpp
2024-03-17 22:07:33 +03:00

893 lines
28 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "cbase.h"
#include "shareddefs.h"
#include "materialsystem/imesh.h"
#include "materialsystem/imaterial.h"
#include "view.h"
#include "iviewrender.h"
#include "view_shared.h"
#include "texture_group_names.h"
#include "tier0/icommandline.h"
#include "vguicenterprint.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
static ConVar scissor("r_flashlightscissor", "0");
//intensity
ConVar csm_intensity("csm_intensity", "200");
ConVar csm_second_intensity("csm_second_intensity", "200");
ConVar csm_third_intensity("csm_third_intensity", "200");
ConVar csm_brightness_general("csm_brightness_general", "1");
ConVar csm_color_r("csm_color_r", "255");
ConVar csm_color_g("csm_color_g", "255");
ConVar csm_color_b("csm_color_b", "255");
ConVar csm_color_a("csm_color_a", "255");
ConVar csm_round_pos("csm_round_pos", "1");
ConVar csm_filter("csm_filter", "1");
ConVar csm_enable("csm_enable", "1");
//-----------------------------------------------------------------------------
// Purpose: main point for change angle of the light
//-----------------------------------------------------------------------------
class C_LightOrigin : public C_BaseEntity
{
DECLARE_CLASS(C_LightOrigin, C_BaseEntity);
public:
DECLARE_CLIENTCLASS();
void Update();
virtual void Simulate();
private:
Vector LightEnvVector;
//QAngle LightEnvAngle;
};
IMPLEMENT_CLIENTCLASS_DT(C_LightOrigin, DT_LightOrigin, CLightOrigin)
RecvPropVector(RECVINFO(LightEnvVector))
END_RECV_TABLE()
void C_LightOrigin::Update()
{
Vector pos = C_BasePlayer::GetLocalPlayer()->GetAbsOrigin();
pos.x = ((int)(pos.x / csm_round_pos.GetInt())) * csm_round_pos.GetInt();
pos.y = ((int)(pos.y / csm_round_pos.GetInt())) * csm_round_pos.GetInt();
pos.z = ((int)(pos.z / csm_round_pos.GetInt())) * csm_round_pos.GetInt();
SetAbsOrigin(pos);
}
void C_LightOrigin::Simulate()
{
Update();
BaseClass::Simulate();
ConVarRef("r_farz").SetValue("210000");
}
//-----------------------------------------------------------------------------
// Purpose: main csm code
//-----------------------------------------------------------------------------
class C_EnvCascadeLight : public C_BaseEntity
{
DECLARE_CLASS(C_EnvCascadeLight, C_BaseEntity);
public:
DECLARE_CLIENTCLASS();
virtual void OnDataChanged(DataUpdateType_t updateType);
void ShutDownLightHandle(void);
virtual void Simulate();
void UpdateLight(bool bForceUpdate);
C_EnvCascadeLight();
~C_EnvCascadeLight();
private:
ClientShadowHandle_t m_LightHandle;
EHANDLE m_hTargetEntity;
//color32 m_LightColor;
#ifdef MAPBASE
float m_flBrightnessScale;
float m_flCurrentBrightnessScale;
#endif
Vector m_CurrentLinearFloatLightColor;
float m_flCurrentLinearFloatLightAlpha;
float m_flColorTransitionTime;
bool m_bState;
float m_flLightFOV;
bool m_bEnableShadows;
bool m_bLightOnlyTarget;
bool m_bLightWorld;
bool m_bCameraSpace;
//Vector m_LinearFloatLightColor;
float m_flAmbient;
float m_flNearZ;
float m_flFarZ;
char m_SpotlightTextureName[MAX_PATH];
int m_nSpotlightTextureFrame;
int m_nShadowQuality;
};
IMPLEMENT_CLIENTCLASS_DT(C_EnvCascadeLight, DT_EnvCascadeLight, CEnvCascadeLight)
RecvPropEHandle( RECVINFO( m_hTargetEntity ) ),
RecvPropBool( RECVINFO( m_bState ) ),
RecvPropFloat( RECVINFO( m_flLightFOV ) ),
RecvPropBool( RECVINFO( m_bEnableShadows ) ),
RecvPropBool( RECVINFO( m_bLightOnlyTarget ) ),
//RecvPropInt(RECVINFO(m_LightColor), 0, RecvProxy_IntToColor32),
RecvPropBool( RECVINFO( m_bLightWorld ) ),
RecvPropBool( RECVINFO( m_bCameraSpace ) ),
//RecvPropVector( RECVINFO( m_LinearFloatLightColor ) ),
RecvPropFloat( RECVINFO( m_flAmbient ) ),
RecvPropString( RECVINFO( m_SpotlightTextureName ) ),
RecvPropInt( RECVINFO( m_nSpotlightTextureFrame ) ),
RecvPropFloat( RECVINFO( m_flNearZ ) ),
RecvPropFloat( RECVINFO( m_flFarZ ) ),
RecvPropInt( RECVINFO( m_nShadowQuality ) )
END_RECV_TABLE()
C_EnvCascadeLight::C_EnvCascadeLight( void )
{
m_LightHandle = CLIENTSHADOW_INVALID_HANDLE;
}
C_EnvCascadeLight::~C_EnvCascadeLight( void )
{
ShutDownLightHandle();
}
void C_EnvCascadeLight::ShutDownLightHandle( void )
{
if (m_LightHandle != CLIENTSHADOW_INVALID_HANDLE)
{
g_pClientShadowMgr->DestroyFlashlight(m_LightHandle);
m_LightHandle = CLIENTSHADOW_INVALID_HANDLE;
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : updateType - how do you increase the light's height?
//-----------------------------------------------------------------------------
void C_EnvCascadeLight::OnDataChanged( DataUpdateType_t updateType )
{
UpdateLight( true );
BaseClass::OnDataChanged( updateType );
}
void C_EnvCascadeLight::UpdateLight( bool bForceUpdate )
{
if (m_bState == false)
{
if(m_LightHandle!=CLIENTSHADOW_INVALID_HANDLE)
ShutDownLightHandle();
return;
}
Vector vForward, vRight, vUp, vPos = GetAbsOrigin();
FlashlightState_t state;
state.m_flShadowFilterSize = csm_filter.GetFloat();
if (m_hTargetEntity != NULL)
{
if (m_bCameraSpace)
{
const QAngle& angles = GetLocalAngles();
C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer();
if (pPlayer)
{
const QAngle playerAngles = pPlayer->GetAbsAngles();
Vector vPlayerForward, vPlayerRight, vPlayerUp;
AngleVectors(playerAngles, &vPlayerForward, &vPlayerRight, &vPlayerUp);
matrix3x4_t mRotMatrix;
AngleMatrix(angles, mRotMatrix);
VectorITransform(vPlayerForward, mRotMatrix, vForward);
VectorITransform(vPlayerRight, mRotMatrix, vRight);
VectorITransform(vPlayerUp, mRotMatrix, vUp);
float dist = (m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin()).Length();
vPos = m_hTargetEntity->GetAbsOrigin() - vForward * dist;
VectorNormalize(vForward);
VectorNormalize(vRight);
VectorNormalize(vUp);
}
}
else
{
vForward = m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin();
VectorNormalize(vForward);
Assert(0);
}
}
else
{
AngleVectors(GetAbsAngles(), &vForward, &vRight, &vUp);
}
Vector vLinearFloatLightColor(csm_color_r.GetInt(), csm_color_g.GetInt(), csm_color_b.GetInt());
float flLinearFloatLightAlpha = csm_color_a.GetInt();
#ifdef MAPBASE
if (m_CurrentLinearFloatLightColor != vLinearFloatLightColor || m_flCurrentLinearFloatLightAlpha != flLinearFloatLightAlpha)
{
if (m_flColorTransitionTime != 0.0f)
{
float flColorTransitionSpeed = gpGlobals->frametime * m_flColorTransitionTime * 255.0f;
m_CurrentLinearFloatLightColor.x = Approach(vLinearFloatLightColor.x, m_CurrentLinearFloatLightColor.x, flColorTransitionSpeed);
m_CurrentLinearFloatLightColor.y = Approach(vLinearFloatLightColor.y, m_CurrentLinearFloatLightColor.y, flColorTransitionSpeed);
m_CurrentLinearFloatLightColor.z = Approach(vLinearFloatLightColor.z, m_CurrentLinearFloatLightColor.z, flColorTransitionSpeed);
m_flCurrentLinearFloatLightAlpha = Approach(flLinearFloatLightAlpha, m_flCurrentLinearFloatLightAlpha, flColorTransitionSpeed);
//m_flCurrentBrightnessScale = Approach(m_flBrightnessScale, m_flCurrentBrightnessScale, flColorTransitionSpeed);
}
else
{
// Just do it instantly
m_CurrentLinearFloatLightColor.x = vLinearFloatLightColor.x;
m_CurrentLinearFloatLightColor.y = vLinearFloatLightColor.y;
m_CurrentLinearFloatLightColor.z = vLinearFloatLightColor.z;
m_flCurrentLinearFloatLightAlpha = flLinearFloatLightAlpha;
//m_flCurrentBrightnessScale = m_flBrightnessScale;
}
}
#else
if (m_CurrentLinearFloatLightColor != vLinearFloatLightColor || m_flCurrentLinearFloatLightAlpha != flLinearFloatLightAlpha)
{
float flColorTransitionSpeed = gpGlobals->frametime * m_flColorTransitionTime * 255.0f;
m_CurrentLinearFloatLightColor.x = Approach(vLinearFloatLightColor.x, m_CurrentLinearFloatLightColor.x, flColorTransitionSpeed);
m_CurrentLinearFloatLightColor.y = Approach(vLinearFloatLightColor.y, m_CurrentLinearFloatLightColor.y, flColorTransitionSpeed);
m_CurrentLinearFloatLightColor.z = Approach(vLinearFloatLightColor.z, m_CurrentLinearFloatLightColor.z, flColorTransitionSpeed);
m_flCurrentLinearFloatLightAlpha = Approach(flLinearFloatLightAlpha, m_flCurrentLinearFloatLightAlpha, flColorTransitionSpeed);
}
#endif
state.m_fHorizontalFOVDegrees = m_flLightFOV;
state.m_fVerticalFOVDegrees = m_flLightFOV;
state.m_vecLightOrigin = vPos;
BasisToQuaternion(vForward, vRight, vUp, state.m_quatOrientation);
state.m_fQuadraticAtten = 0.0;
state.m_fLinearAtten = 100;
state.m_fConstantAtten = 0.0f;
//state.m_Color[0] = m_LinearFloatLightColor.x;
//state.m_Color[1] = m_LinearFloatLightColor.y;
//state.m_Color[2] = m_LinearFloatLightColor.z;
#ifdef MAPBASE
float flAlpha = m_flCurrentLinearFloatLightAlpha * (1.0f / 255.0f);
state.m_Color[0] = (m_CurrentLinearFloatLightColor.x * (1.0f / 255.0f) * flAlpha) * csm_intensity.GetFloat() * csm_brightness_general.GetFloat();
state.m_Color[1] = (m_CurrentLinearFloatLightColor.y * (1.0f / 255.0f) * flAlpha) * csm_intensity.GetFloat() * csm_brightness_general.GetFloat();
state.m_Color[2] = (m_CurrentLinearFloatLightColor.z * (1.0f / 255.0f) * flAlpha) * csm_intensity.GetFloat() * csm_brightness_general.GetFloat();
#else
state.m_Color[0] = m_CurrentLinearFloatLightColor.x * (1.0f / 255.0f) * csm_intensity.GetFloat();
state.m_Color[1] = m_CurrentLinearFloatLightColor.y * (1.0f / 255.0f) * csm_intensity.GetFloat();
state.m_Color[2] = m_CurrentLinearFloatLightColor.z * (1.0f / 255.0f) * csm_intensity.GetFloat();
#endif
state.m_Color[3] = m_flAmbient; // fixme: need to make ambient work m_flAmbient;
state.m_NearZ = m_flNearZ;
state.m_FarZ = m_flFarZ;
state.m_flShadowSlopeScaleDepthBias = ConVarRef("mat_slopescaledepthbias_shadowmap").GetFloat();//csm_slopescaledepthbias_shadowmap.GetFloat();
state.m_flShadowDepthBias = ConVarRef("mat_depthbias_shadowmap").GetFloat();//csm_depthbias_shadowmap.GetFloat();
state.m_bEnableShadows = m_bEnableShadows;
state.m_pSpotlightTexture = materials->FindTexture(m_SpotlightTextureName, TEXTURE_GROUP_OTHER, false);
state.m_nSpotlightTextureFrame = m_nSpotlightTextureFrame;
state.m_nShadowQuality = m_nShadowQuality; // Allow entity to affect shadow quality
if (m_LightHandle == CLIENTSHADOW_INVALID_HANDLE)
{
m_LightHandle = g_pClientShadowMgr->CreateFlashlight(state);
}
else
{
if (m_hTargetEntity != NULL || bForceUpdate == true)
{
g_pClientShadowMgr->UpdateFlashlightState(m_LightHandle, state);
}
}
if (m_bLightOnlyTarget)
{
g_pClientShadowMgr->SetFlashlightTarget(m_LightHandle, m_hTargetEntity);
}
else
{
g_pClientShadowMgr->SetFlashlightTarget(m_LightHandle, NULL);
}
g_pClientShadowMgr->SetFlashlightLightWorld(m_LightHandle, m_bLightWorld);
g_pClientShadowMgr->UpdateProjectedTexture(m_LightHandle, true);
}
void C_EnvCascadeLight::Simulate( void )
{
m_bState = csm_enable.GetBool();
UpdateLight(true);
BaseClass::Simulate();
}
//-----------------------------------------------------------------------------
// Purpose: second csm
//-----------------------------------------------------------------------------
class C_EnvCascadeLightSecond : public C_BaseEntity
{
DECLARE_CLASS(C_EnvCascadeLightSecond, C_BaseEntity);
public:
DECLARE_CLIENTCLASS();
virtual void OnDataChanged(DataUpdateType_t updateType);
void ShutDownLightHandle(void);
virtual void Simulate();
void UpdateLight(bool bForceUpdate);
void updatePos();
C_EnvCascadeLightSecond();
~C_EnvCascadeLightSecond();
private:
ClientShadowHandle_t m_LightHandle;
//color32 m_LightColor;
#ifdef MAPBASE
float m_flBrightnessScale;
float m_flCurrentBrightnessScale;
#endif
Vector m_CurrentLinearFloatLightColor;
float m_flCurrentLinearFloatLightAlpha;
float m_flColorTransitionTime;
EHANDLE m_hTargetEntity;
CBaseEntity* pEntity = NULL;
bool firstUpdate = true;
bool m_bState;
float m_flLightFOV;
bool m_bEnableShadows;
bool m_bLightOnlyTarget;
bool m_bLightWorld;
bool m_bCameraSpace;
//Vector m_LinearFloatLightColor;
float m_flAmbient;
float m_flNearZ;
float m_flFarZ;
char m_SpotlightTextureName[MAX_PATH];
int m_nSpotlightTextureFrame;
int m_nShadowQuality;
};
IMPLEMENT_CLIENTCLASS_DT(C_EnvCascadeLightSecond, DT_EnvCascadeLightSecond, CEnvCascadeLightSecond)
//RecvPropInt(RECVINFO(m_LightColor), 0, RecvProxy_IntToColor32),
RecvPropEHandle(RECVINFO(m_hTargetEntity)),
RecvPropBool(RECVINFO(m_bState)),
RecvPropFloat(RECVINFO(m_flLightFOV)),
RecvPropBool(RECVINFO(m_bEnableShadows)),
RecvPropBool(RECVINFO(m_bLightOnlyTarget)),
RecvPropBool(RECVINFO(m_bLightWorld)),
RecvPropBool(RECVINFO(m_bCameraSpace)),
//RecvPropVector(RECVINFO(m_LinearFloatLightColor)),
RecvPropFloat(RECVINFO(m_flAmbient)),
RecvPropString(RECVINFO(m_SpotlightTextureName)),
RecvPropInt(RECVINFO(m_nSpotlightTextureFrame)),
RecvPropFloat(RECVINFO(m_flNearZ)),
RecvPropFloat(RECVINFO(m_flFarZ)),
RecvPropInt(RECVINFO(m_nShadowQuality))
END_RECV_TABLE()
C_EnvCascadeLightSecond::C_EnvCascadeLightSecond(void)
{
m_LightHandle = CLIENTSHADOW_INVALID_HANDLE;
}
C_EnvCascadeLightSecond::~C_EnvCascadeLightSecond(void)
{
ShutDownLightHandle();
}
void C_EnvCascadeLightSecond::ShutDownLightHandle(void)
{
if (m_LightHandle != CLIENTSHADOW_INVALID_HANDLE)
{
g_pClientShadowMgr->DestroyFlashlight(m_LightHandle);
m_LightHandle = CLIENTSHADOW_INVALID_HANDLE;
}
}
void C_EnvCascadeLightSecond::OnDataChanged(DataUpdateType_t updateType)
{
UpdateLight(true);
BaseClass::OnDataChanged(updateType);
}
void C_EnvCascadeLightSecond::UpdateLight(bool bForceUpdate)
{
if (m_bState == false)
{
if(m_LightHandle!=CLIENTSHADOW_INVALID_HANDLE)
ShutDownLightHandle();
return;
}
Vector vForward, vRight, vUp, vPos = GetAbsOrigin();
FlashlightState_t state;
state.m_flShadowFilterSize = csm_filter.GetFloat();
if (m_hTargetEntity != NULL)
{
if (m_bCameraSpace)
{
const QAngle& angles = GetLocalAngles();
C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer();
if (pPlayer)
{
const QAngle playerAngles = pPlayer->GetAbsAngles();
Vector vPlayerForward, vPlayerRight, vPlayerUp;
AngleVectors(playerAngles, &vPlayerForward, &vPlayerRight, &vPlayerUp);
matrix3x4_t mRotMatrix;
AngleMatrix(angles, mRotMatrix);
VectorITransform(vPlayerForward, mRotMatrix, vForward);
VectorITransform(vPlayerRight, mRotMatrix, vRight);
VectorITransform(vPlayerUp, mRotMatrix, vUp);
float dist = (m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin()).Length();
vPos = m_hTargetEntity->GetAbsOrigin() - vForward * dist;
VectorNormalize(vForward);
VectorNormalize(vRight);
VectorNormalize(vUp);
}
}
else
{
vForward = m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin();
VectorNormalize(vForward);
Assert(0);
}
}
else
{
AngleVectors(GetAbsAngles(), &vForward, &vRight, &vUp);
}
Vector vLinearFloatLightColor(csm_color_r.GetInt(), csm_color_g.GetInt(), csm_color_b.GetInt());
float flLinearFloatLightAlpha = csm_color_a.GetInt();
#ifdef MAPBASE
if (m_CurrentLinearFloatLightColor != vLinearFloatLightColor || m_flCurrentLinearFloatLightAlpha != flLinearFloatLightAlpha)
{
if (m_flColorTransitionTime != 0.0f)
{
float flColorTransitionSpeed = gpGlobals->frametime * m_flColorTransitionTime * 255.0f;
m_CurrentLinearFloatLightColor.x = Approach(vLinearFloatLightColor.x, m_CurrentLinearFloatLightColor.x, flColorTransitionSpeed);
m_CurrentLinearFloatLightColor.y = Approach(vLinearFloatLightColor.y, m_CurrentLinearFloatLightColor.y, flColorTransitionSpeed);
m_CurrentLinearFloatLightColor.z = Approach(vLinearFloatLightColor.z, m_CurrentLinearFloatLightColor.z, flColorTransitionSpeed);
m_flCurrentLinearFloatLightAlpha = Approach(flLinearFloatLightAlpha, m_flCurrentLinearFloatLightAlpha, flColorTransitionSpeed);
//m_flCurrentBrightnessScale = Approach(m_flBrightnessScale, m_flCurrentBrightnessScale, flColorTransitionSpeed);
}
else
{
// Just do it instantly
m_CurrentLinearFloatLightColor.x = vLinearFloatLightColor.x;
m_CurrentLinearFloatLightColor.y = vLinearFloatLightColor.y;
m_CurrentLinearFloatLightColor.z = vLinearFloatLightColor.z;
m_flCurrentLinearFloatLightAlpha = flLinearFloatLightAlpha;
//m_flCurrentBrightnessScale = m_flBrightnessScale;
}
}
#else
if (m_CurrentLinearFloatLightColor != vLinearFloatLightColor || m_flCurrentLinearFloatLightAlpha != flLinearFloatLightAlpha)
{
float flColorTransitionSpeed = gpGlobals->frametime * m_flColorTransitionTime * 255.0f;
m_CurrentLinearFloatLightColor.x = Approach(vLinearFloatLightColor.x, m_CurrentLinearFloatLightColor.x, flColorTransitionSpeed);
m_CurrentLinearFloatLightColor.y = Approach(vLinearFloatLightColor.y, m_CurrentLinearFloatLightColor.y, flColorTransitionSpeed);
m_CurrentLinearFloatLightColor.z = Approach(vLinearFloatLightColor.z, m_CurrentLinearFloatLightColor.z, flColorTransitionSpeed);
m_flCurrentLinearFloatLightAlpha = Approach(flLinearFloatLightAlpha, m_flCurrentLinearFloatLightAlpha, flColorTransitionSpeed);
}
#endif
state.m_fHorizontalFOVDegrees = m_flLightFOV;
state.m_fVerticalFOVDegrees = m_flLightFOV;
state.m_vecLightOrigin = vPos;
BasisToQuaternion(vForward, vRight, vUp, state.m_quatOrientation);
state.m_fQuadraticAtten = 0.0;
state.m_fLinearAtten = 100;
state.m_fConstantAtten = 0.0f;
#ifdef MAPBASE
float flAlpha = m_flCurrentLinearFloatLightAlpha * (1.0f / 255.0f);
state.m_Color[0] = (m_CurrentLinearFloatLightColor.x * (1.0f / 255.0f) * flAlpha) * csm_second_intensity.GetFloat() * csm_brightness_general.GetFloat();
state.m_Color[1] = (m_CurrentLinearFloatLightColor.y * (1.0f / 255.0f) * flAlpha) * csm_second_intensity.GetFloat() * csm_brightness_general.GetFloat();
state.m_Color[2] = (m_CurrentLinearFloatLightColor.z * (1.0f / 255.0f) * flAlpha) * csm_second_intensity.GetFloat() * csm_brightness_general.GetFloat();
#else
state.m_Color[0] = m_CurrentLinearFloatLightColor.x * (1.0f / 255.0f) * csm_second_intensity.GetFloat();
state.m_Color[1] = m_CurrentLinearFloatLightColor.y * (1.0f / 255.0f) * csm_second_intensity.GetFloat();
state.m_Color[2] = m_CurrentLinearFloatLightColor.z * (1.0f / 255.0f) * csm_second_intensity.GetFloat();
#endif
state.m_Color[3] = 0.0f; // fixme: need to make ambient work m_flAmbient;
state.m_NearZ = m_flNearZ;
state.m_FarZ = m_flFarZ;
state.m_flShadowSlopeScaleDepthBias = ConVarRef("mat_slopescaledepthbias_shadowmap").GetFloat();
state.m_flShadowDepthBias = ConVarRef("mat_depthbias_shadowmap").GetFloat();
state.m_bEnableShadows = m_bEnableShadows;
state.m_pSpotlightTexture = materials->FindTexture(m_SpotlightTextureName, TEXTURE_GROUP_OTHER, false);
state.m_nSpotlightTextureFrame = m_nSpotlightTextureFrame;
state.m_nShadowQuality = m_nShadowQuality; // Allow entity to affect shadow quality
if (m_LightHandle == CLIENTSHADOW_INVALID_HANDLE)
{
m_LightHandle = g_pClientShadowMgr->CreateFlashlight(state);
}
else
{
if (m_hTargetEntity != NULL || bForceUpdate == true)
{
g_pClientShadowMgr->UpdateFlashlightState(m_LightHandle, state);
}
}
if (m_bLightOnlyTarget)
{
g_pClientShadowMgr->SetFlashlightTarget(m_LightHandle, m_hTargetEntity);
}
else
{
g_pClientShadowMgr->SetFlashlightTarget(m_LightHandle, NULL);
}
g_pClientShadowMgr->SetFlashlightLightWorld(m_LightHandle, m_bLightWorld);
g_pClientShadowMgr->UpdateProjectedTexture(m_LightHandle, true);
scissor.SetValue("0");
}
void C_EnvCascadeLightSecond::Simulate(void)
{
m_bState = csm_enable.GetBool();
UpdateLight(true);
BaseClass::Simulate();
}
//-----------------------------------------------------------------------------
// Purpose: second csm
//-----------------------------------------------------------------------------
class C_EnvCascadeLightThird : public C_BaseEntity
{
DECLARE_CLASS(C_EnvCascadeLightThird, C_BaseEntity);
public:
DECLARE_CLIENTCLASS();
virtual void OnDataChanged(DataUpdateType_t updateType);
void ShutDownLightHandle(void);
virtual void Simulate();
void UpdateLight(bool bForceUpdate);
void updatePos();
C_EnvCascadeLightThird();
~C_EnvCascadeLightThird();
private:
ClientShadowHandle_t m_LightHandle;
//color32 m_LightColor;
#ifdef MAPBASE
float m_flBrightnessScale;
float m_flCurrentBrightnessScale;
#endif
Vector m_CurrentLinearFloatLightColor;
float m_flCurrentLinearFloatLightAlpha;
float m_flColorTransitionTime;
EHANDLE m_hTargetEntity;
CBaseEntity* pEntity = NULL;
bool firstUpdate = true;
bool m_bState;
float m_flLightFOV;
bool m_bEnableShadows;
bool m_bLightOnlyTarget;
bool m_bLightWorld;
bool m_bCameraSpace;
//Vector m_LinearFloatLightColor;
float m_flAmbient;
float m_flNearZ;
float m_flFarZ;
char m_SpotlightTextureName[MAX_PATH];
int m_nSpotlightTextureFrame;
int m_nShadowQuality;
};
IMPLEMENT_CLIENTCLASS_DT(C_EnvCascadeLightThird, DT_EnvCascadeLightThird, CEnvCascadeLightThird)
//RecvPropInt(RECVINFO(m_LightColor), 0, RecvProxy_IntToColor32),
RecvPropEHandle(RECVINFO(m_hTargetEntity)),
RecvPropBool(RECVINFO(m_bState)),
RecvPropFloat(RECVINFO(m_flLightFOV)),
RecvPropBool(RECVINFO(m_bEnableShadows)),
RecvPropBool(RECVINFO(m_bLightOnlyTarget)),
RecvPropBool(RECVINFO(m_bLightWorld)),
RecvPropBool(RECVINFO(m_bCameraSpace)),
//RecvPropVector(RECVINFO(m_LinearFloatLightColor)),
RecvPropFloat(RECVINFO(m_flAmbient)),
RecvPropString(RECVINFO(m_SpotlightTextureName)),
RecvPropInt(RECVINFO(m_nSpotlightTextureFrame)),
RecvPropFloat(RECVINFO(m_flNearZ)),
RecvPropFloat(RECVINFO(m_flFarZ)),
RecvPropInt(RECVINFO(m_nShadowQuality))
END_RECV_TABLE()
C_EnvCascadeLightThird::C_EnvCascadeLightThird(void)
{
m_LightHandle = CLIENTSHADOW_INVALID_HANDLE;
}
C_EnvCascadeLightThird::~C_EnvCascadeLightThird(void)
{
ShutDownLightHandle();
}
void C_EnvCascadeLightThird::ShutDownLightHandle(void)
{
if (m_LightHandle != CLIENTSHADOW_INVALID_HANDLE)
{
g_pClientShadowMgr->DestroyFlashlight(m_LightHandle);
m_LightHandle = CLIENTSHADOW_INVALID_HANDLE;
}
}
void C_EnvCascadeLightThird::OnDataChanged(DataUpdateType_t updateType)
{
UpdateLight(true);
BaseClass::OnDataChanged(updateType);
}
void C_EnvCascadeLightThird::UpdateLight(bool bForceUpdate)
{
if (m_bState == false)
{
if (m_LightHandle != CLIENTSHADOW_INVALID_HANDLE)
ShutDownLightHandle();
return;
}
Vector vForward, vRight, vUp, vPos = GetAbsOrigin();
FlashlightState_t state;
state.m_flShadowFilterSize = csm_filter.GetFloat();
if (m_hTargetEntity != NULL)
{
if (m_bCameraSpace)
{
const QAngle& angles = GetLocalAngles();
C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer();
if (pPlayer)
{
const QAngle playerAngles = pPlayer->GetAbsAngles();
Vector vPlayerForward, vPlayerRight, vPlayerUp;
AngleVectors(playerAngles, &vPlayerForward, &vPlayerRight, &vPlayerUp);
matrix3x4_t mRotMatrix;
AngleMatrix(angles, mRotMatrix);
VectorITransform(vPlayerForward, mRotMatrix, vForward);
VectorITransform(vPlayerRight, mRotMatrix, vRight);
VectorITransform(vPlayerUp, mRotMatrix, vUp);
float dist = (m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin()).Length();
vPos = m_hTargetEntity->GetAbsOrigin() - vForward * dist;
VectorNormalize(vForward);
VectorNormalize(vRight);
VectorNormalize(vUp);
}
}
else
{
vForward = m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin();
VectorNormalize(vForward);
Assert(0);
}
}
else
{
AngleVectors(GetAbsAngles(), &vForward, &vRight, &vUp);
}
Vector vLinearFloatLightColor(csm_color_r.GetInt(), csm_color_g.GetInt(), csm_color_b.GetInt());
float flLinearFloatLightAlpha = csm_color_a.GetInt();
#ifdef MAPBASE
if (m_CurrentLinearFloatLightColor != vLinearFloatLightColor || m_flCurrentLinearFloatLightAlpha != flLinearFloatLightAlpha)
{
if (m_flColorTransitionTime != 0.0f)
{
float flColorTransitionSpeed = gpGlobals->frametime * m_flColorTransitionTime * 255.0f;
m_CurrentLinearFloatLightColor.x = Approach(vLinearFloatLightColor.x, m_CurrentLinearFloatLightColor.x, flColorTransitionSpeed);
m_CurrentLinearFloatLightColor.y = Approach(vLinearFloatLightColor.y, m_CurrentLinearFloatLightColor.y, flColorTransitionSpeed);
m_CurrentLinearFloatLightColor.z = Approach(vLinearFloatLightColor.z, m_CurrentLinearFloatLightColor.z, flColorTransitionSpeed);
m_flCurrentLinearFloatLightAlpha = Approach(flLinearFloatLightAlpha, m_flCurrentLinearFloatLightAlpha, flColorTransitionSpeed);
//m_flCurrentBrightnessScale = Approach(m_flBrightnessScale, m_flCurrentBrightnessScale, flColorTransitionSpeed);
}
else
{
// Just do it instantly
m_CurrentLinearFloatLightColor.x = vLinearFloatLightColor.x;
m_CurrentLinearFloatLightColor.y = vLinearFloatLightColor.y;
m_CurrentLinearFloatLightColor.z = vLinearFloatLightColor.z;
m_flCurrentLinearFloatLightAlpha = flLinearFloatLightAlpha;
//m_flCurrentBrightnessScale = m_flBrightnessScale;
}
}
#else
if (m_CurrentLinearFloatLightColor != vLinearFloatLightColor || m_flCurrentLinearFloatLightAlpha != flLinearFloatLightAlpha)
{
float flColorTransitionSpeed = gpGlobals->frametime * m_flColorTransitionTime * 255.0f;
m_CurrentLinearFloatLightColor.x = Approach(vLinearFloatLightColor.x, m_CurrentLinearFloatLightColor.x, flColorTransitionSpeed);
m_CurrentLinearFloatLightColor.y = Approach(vLinearFloatLightColor.y, m_CurrentLinearFloatLightColor.y, flColorTransitionSpeed);
m_CurrentLinearFloatLightColor.z = Approach(vLinearFloatLightColor.z, m_CurrentLinearFloatLightColor.z, flColorTransitionSpeed);
m_flCurrentLinearFloatLightAlpha = Approach(flLinearFloatLightAlpha, m_flCurrentLinearFloatLightAlpha, flColorTransitionSpeed);
}
#endif
state.m_fHorizontalFOVDegrees = m_flLightFOV;
state.m_fVerticalFOVDegrees = m_flLightFOV;
state.m_vecLightOrigin = vPos;
BasisToQuaternion(vForward, vRight, vUp, state.m_quatOrientation);
state.m_fQuadraticAtten = 0.0;
state.m_fLinearAtten = 100;
state.m_fConstantAtten = 0.0f;
//state.m_Color[0] = m_LinearFloatLightColor.x;
//state.m_Color[1] = m_LinearFloatLightColor.y;
//state.m_Color[2] = m_LinearFloatLightColor.z;
#ifdef MAPBASE
float flAlpha = m_flCurrentLinearFloatLightAlpha * (1.0f / 255.0f);
state.m_Color[0] = (m_CurrentLinearFloatLightColor.x * (1.0f / 255.0f) * flAlpha) * csm_third_intensity.GetFloat() * csm_brightness_general.GetFloat();
state.m_Color[1] = (m_CurrentLinearFloatLightColor.y * (1.0f / 255.0f) * flAlpha) * csm_third_intensity.GetFloat() * csm_brightness_general.GetFloat();
state.m_Color[2] = (m_CurrentLinearFloatLightColor.z * (1.0f / 255.0f) * flAlpha) * csm_third_intensity.GetFloat() * csm_brightness_general.GetFloat();
#else
state.m_Color[0] = m_CurrentLinearFloatLightColor.x * (1.0f / 255.0f) * csm_third_intensity.GetFloat();
state.m_Color[1] = m_CurrentLinearFloatLightColor.y * (1.0f / 255.0f) * csm_third_intensity.GetFloat();
state.m_Color[2] = m_CurrentLinearFloatLightColor.z * (1.0f / 255.0f) * csm_third_intensity.GetFloat();
#endif
state.m_Color[3] = 0.0f; // fixme: need to make ambient work m_flAmbient;
state.m_NearZ = m_flNearZ;
state.m_FarZ = m_flFarZ;
state.m_flShadowSlopeScaleDepthBias = ConVarRef("mat_slopescaledepthbias_shadowmap").GetFloat();//csm_slopescaledepthbias_shadowmap.GetFloat();
state.m_flShadowDepthBias = ConVarRef("mat_depthbias_shadowmap").GetFloat();//csm_depthbias_shadowmap.GetFloat();
state.m_bEnableShadows = m_bEnableShadows;
state.m_pSpotlightTexture = materials->FindTexture(m_SpotlightTextureName, TEXTURE_GROUP_OTHER, false);
state.m_nSpotlightTextureFrame = m_nSpotlightTextureFrame;
state.m_nShadowQuality = m_nShadowQuality; // Allow entity to affect shadow quality
if (m_LightHandle == CLIENTSHADOW_INVALID_HANDLE)
{
m_LightHandle = g_pClientShadowMgr->CreateFlashlight(state);
}
else
{
if (m_hTargetEntity != NULL || bForceUpdate == true)
{
g_pClientShadowMgr->UpdateFlashlightState(m_LightHandle, state);
}
}
if (m_bLightOnlyTarget)
{
g_pClientShadowMgr->SetFlashlightTarget(m_LightHandle, m_hTargetEntity);
}
else
{
g_pClientShadowMgr->SetFlashlightTarget(m_LightHandle, NULL);
}
g_pClientShadowMgr->SetFlashlightLightWorld(m_LightHandle, m_bLightWorld);
#ifdef MAPBASE
if (state.m_bOrtho)
{
bool bSupressWorldLights = false;
bSupressWorldLights = m_bEnableShadows;
g_pClientShadowMgr->SetShadowFromWorldLightsEnabled(!bSupressWorldLights);
}
#endif // MAPBASE
g_pClientShadowMgr->UpdateProjectedTexture(m_LightHandle, true);
scissor.SetValue("0");
}
void C_EnvCascadeLightThird::Simulate(void)
{
m_bState = csm_enable.GetBool();
UpdateLight(true);
BaseClass::Simulate();
}