diff --git a/client/C_Env_Cascade_Light.h b/client/C_Env_Cascade_Light.h new file mode 100644 index 0000000..8bb7661 --- /dev/null +++ b/client/C_Env_Cascade_Light.h @@ -0,0 +1,76 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef C_ENVPROJECTEDTEXTURE_H +#define C_ENVPROJECTEDTEXTURE_H +#ifdef _WIN32 +#pragma once +#endif + +#include "c_baseentity.h" +#include "basetypes.h" + +class C_LightOrigin : public C_BaseEntity +{ + DECLARE_CLASS(C_LightOrigin, C_BaseEntity); +public: + DECLARE_CLIENTCLASS(); + + +private: +}; + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- + +class C_EnvCascadeLight : public C_BaseEntity +{ + DECLARE_CLASS(C_EnvCascadeLight, C_BaseEntity ); +public: + DECLARE_CLIENTCLASS(); + + C_EnvCascadeLight(); + ~C_EnvCascadeLight(); + + virtual void OnDataChanged( DataUpdateType_t updateType ); + void ShutDownLightHandle( void ); + + virtual void Simulate(); + + void UpdateLight( bool bForceUpdate ); + + bool ShadowsEnabled(); + + float GetFOV(); + +private: + + ClientShadowHandle_t m_LightHandle; + + EHANDLE m_hTargetEntity; + bool m_bState; + float m_flLightFOV; + bool m_bEnableShadows; + bool m_bLightOnlyTarget; + bool m_bLightWorld; + bool m_bCameraSpace; + color32 m_cLightColor; + float m_flAmbient; + char m_SpotlightTextureName[ MAX_PATH ]; + int m_nSpotlightTextureFrame; + int m_nShadowQuality; + bool m_bCurrentShadow; + +public: + C_EnvCascadeLight*m_pNext; +}; + +C_EnvCascadeLight* GetEnvProjectedTextureList(); + +#endif // C_ENVPROJECTEDTEXTURE_H diff --git a/client/c_env_cascade_light.cpp b/client/c_env_cascade_light.cpp new file mode 100644 index 0000000..d7bcb36 --- /dev/null +++ b/client/c_env_cascade_light.cpp @@ -0,0 +1,553 @@ +//========= 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 ConVarRef mat_slopescaledepthbias_shadowmap("mat_slopescaledepthbias_shadowmap"); +static ConVarRef mat_depthbias_shadowmap("mat_depthbias_shadowmap"); +static ConVar scissor("r_flashlightscissor", "0"); + +static ConVar csm_ortho("csm_ortho","0"); +ConVar csm_ortho_nearz("csm_ortho_nearz", "512"); +ConVar csm_ortho_left("csm_ortho_left", "-1000"); +ConVar csm_ortho_top("csm_ortho_top", "-1000"); +ConVar csm_ortho_bottom("csm_ortho_bottom", "1000"); +ConVar csm_ortho_right("csm_ortho_right", "1000"); +ConVar csm_test_color_interpolation("csm_test_color_interpolation","0"); + +//----------------------------------------------------------------------------- +// 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() +{ + SetAbsOrigin(C_BasePlayer::GetLocalPlayer()->GetAbsOrigin()); +} + + +void C_LightOrigin::Simulate() +{ + Update(); + BaseClass::Simulate(); +} + +const char* filter = CommandLine()->ParmValue("-ptfilter", "0.5"); +ConVar bebra("csm_filter", filter); + +//----------------------------------------------------------------------------- +// 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; + + void updatePos(); + 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_EnvCascadeLight, DT_EnvCascadeLight, CEnvCascadeLight) + 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_EnvCascadeLight::C_EnvCascadeLight( void ) +{ + + m_LightHandle = CLIENTSHADOW_INVALID_HANDLE; +} + + +C_EnvCascadeLight::~C_EnvCascadeLight( void ) +{ + ShutDownLightHandle(); +} + +void C_EnvCascadeLight::ShutDownLightHandle( void ) +{ + // Clear out the light + if( m_LightHandle != CLIENTSHADOW_INVALID_HANDLE ) + { + g_pClientShadowMgr->DestroyFlashlight( m_LightHandle ); + m_LightHandle = CLIENTSHADOW_INVALID_HANDLE; + } +} + +void C_EnvCascadeLight::updatePos() +{ + if (firstUpdate) + { + m_flNearZ = 4000; + m_flFarZ = 16000; + } +} + +//----------------------------------------------------------------------------- +// 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 = bebra.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); + } + + + 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; + 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 = mat_slopescaledepthbias_shadowmap.GetFloat(); + state.m_flShadowDepthBias = 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 + + state.m_bOrtho = csm_ortho.GetBool(); + if (state.m_bOrtho) + { + state.m_fOrthoLeft = csm_ortho_left.GetInt(); + state.m_fOrthoTop = csm_ortho_top.GetInt(); + state.m_fOrthoRight = csm_ortho_right.GetInt(); + state.m_fOrthoBottom = csm_ortho_bottom.GetInt(); + + state.m_fLinearAtten = ConVarRef("csm_current_distance").GetInt() * 2; + state.m_FarZAtten = ConVarRef("csm_current_distance").GetInt() * 2; + } + + + + 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); + + mat_slopescaledepthbias_shadowmap.SetValue("4"); + mat_depthbias_shadowmap.SetValue("0.000001"); + scissor.SetValue("0"); + +} + +void C_EnvCascadeLight::Simulate( void ) +{ + UpdateLight( true ); + updatePos(); + firstUpdate = false; + 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; + + 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) +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) +{ + // Clear out the light + 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 = bebra.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); + } + + + 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; + 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 = mat_slopescaledepthbias_shadowmap.GetFloat(); + state.m_flShadowDepthBias = 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 + + state.m_bOrtho = csm_ortho.GetBool(); + if(state.m_bOrtho) + { + float flOrthoSize = 1000.0f; + + state.m_fOrthoLeft = -flOrthoSize; + state.m_fOrthoTop = -flOrthoSize; + state.m_fOrthoRight = flOrthoSize; + state.m_fOrthoBottom = flOrthoSize; + + state.m_fLinearAtten = ConVarRef("csm_current_distance").GetInt() * 2; + state.m_FarZAtten = ConVarRef("csm_current_distance").GetInt() * 2; + } + + + + 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); + + + if (state.m_bOrtho) + { + bool bSupressWorldLights = false; + + bSupressWorldLights = m_bEnableShadows; + + g_pClientShadowMgr->SetShadowFromWorldLightsEnabled(!bSupressWorldLights); + } + + g_pClientShadowMgr->UpdateProjectedTexture(m_LightHandle, true); + + m_flLightFOV = ConVarRef("csm_second_fov").GetFloat(); + + mat_slopescaledepthbias_shadowmap.SetValue("4"); + mat_depthbias_shadowmap.SetValue("0.000001"); + scissor.SetValue("0"); + +} + + +void C_EnvCascadeLightSecond::Simulate(void) +{ + UpdateLight(true); + BaseClass::Simulate(); +} diff --git a/client/csm.vpc b/client/csm.vpc new file mode 100644 index 0000000..66fedbf --- /dev/null +++ b/client/csm.vpc @@ -0,0 +1,13 @@ + +$Project +{ + + $Folder "Source Files" + { + + $File "c_env_cascade_light.cpp" + $File "C_Env_Cascade_Light.h" + + } + +} diff --git a/materials/tools/fakecsm/mask_center.vtf b/materials/tools/fakecsm/mask_center.vtf new file mode 100644 index 0000000..48aeffe Binary files /dev/null and b/materials/tools/fakecsm/mask_center.vtf differ diff --git a/materials/tools/fakecsm/mask_ring.vtf b/materials/tools/fakecsm/mask_ring.vtf new file mode 100644 index 0000000..2e2fd8b Binary files /dev/null and b/materials/tools/fakecsm/mask_ring.vtf differ diff --git a/server/csm.vpc b/server/csm.vpc new file mode 100644 index 0000000..45300a6 --- /dev/null +++ b/server/csm.vpc @@ -0,0 +1,9 @@ + + +$Project +{ + $Folder "Source Files" + { + $File "env_cascade_light.cpp" + } +} diff --git a/server/env_cascade_light.cpp b/server/env_cascade_light.cpp new file mode 100644 index 0000000..612864f --- /dev/null +++ b/server/env_cascade_light.cpp @@ -0,0 +1,491 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Entity to control screen overlays on a player +// +//============================================================================= + +#include "cbase.h" +#include "shareddefs.h" +#include "lights.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#define ENV_CASCADE_STARTON (1<<0) + +static ConVar defdist("csm_default_distance", "1000", 0, "Default Z distance. Used for some fov calculations"); +static ConVar curdist("csm_current_distance","14000", 0, "i like nagatoro"); + +static ConVar defFOV("csm_default_fov","15", 0, "Default FOV. Used for some fov calculations"); +static ConVar curFOV("csm_current_fov","15", FCVAR_DEVELOPMENTONLY, "Current FOV. Please dont change by yourself, please."); +static ConVar csm_second_fov("csm_second_fov", "17", FCVAR_NONE ,"FOV of the second csm."); + +class CLightOrigin : public CPointEntity +{ + DECLARE_CLASS(CLightOrigin, CPointEntity); +public: + DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); + + void Spawn(); + + CLightOrigin(); + + bool angFEnv = true; + + void InitialThink(void); + +private: + + CNetworkVector(LightEnvVector); +}; + +LINK_ENTITY_TO_CLASS(csmorigin, CLightOrigin); + +BEGIN_DATADESC(CLightOrigin) +DEFINE_FIELD(LightEnvVector, FIELD_VECTOR), +DEFINE_THINKFUNC(InitialThink) +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST(CLightOrigin, DT_LightOrigin) +SendPropVector(SENDINFO(LightEnvVector)) +END_SEND_TABLE() + +CLightOrigin::CLightOrigin() +{ +} + +void CLightOrigin::Spawn() +{ + if (angFEnv) + { + CBaseEntity* pEntity = NULL; + pEntity = gEntList.FindEntityByClassname(pEntity, "light_environment"); + if (pEntity) + { + CEnvLight* pEnv = dynamic_cast(pEntity); + + QAngle bb = pEnv->GetAbsAngles(); + bb.x = bb.x; + SetAbsAngles(bb); + //Msg("light_environment Founded!\n"); + ConColorMsg(Color(0,230,0), "light_environment Founded!\n"); + } + else + { + //Msg("What the fuck? Map dont have light_environment with targetname!"); + ConColorMsg(Color(230, 0, 0), "What the fuck? Map dont have light_environment with targetname!\n"); + } + } +} + +void CLightOrigin::InitialThink() +{ +} + + +//----------------------------------------------------------------------------- +// Purpose: second csm +//----------------------------------------------------------------------------- + +class CEnvCascadeLightSecond : public CPointEntity +{ + DECLARE_CLASS(CEnvCascadeLightSecond, CPointEntity); +public: + DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); + + CEnvCascadeLightSecond(); + bool KeyValue(const char* szKeyName, const char* szValue); + + // Always transmit to clients + virtual int UpdateTransmitState(); + virtual void Activate(void); + + void InitialThink(void); + + CNetworkHandle(CBaseEntity, m_hTargetEntity); + CNetworkVector(m_LinearFloatLightColor); + +private: + CNetworkVar(bool, m_bState); + CNetworkVar(float, m_flLightFOV); + CNetworkVar(bool, m_bEnableShadows); + CNetworkVar(bool, m_bLightOnlyTarget); + CNetworkVar(bool, m_bLightWorld); + CNetworkVar(bool, m_bCameraSpace); + CNetworkVar(float, m_flAmbient); + CNetworkString(m_SpotlightTextureName, MAX_PATH); + CNetworkVar(int, m_nSpotlightTextureFrame); + CNetworkVar(float, m_flNearZ); + CNetworkVar(float, m_flFarZ); + CNetworkVar(int, m_nShadowQuality); +}; + +LINK_ENTITY_TO_CLASS(second_csm, CEnvCascadeLightSecond); + +BEGIN_DATADESC(CEnvCascadeLightSecond) +DEFINE_FIELD(m_hTargetEntity, FIELD_EHANDLE), +DEFINE_FIELD(m_bState, FIELD_BOOLEAN), +DEFINE_KEYFIELD(m_flLightFOV, FIELD_FLOAT, "lightfov"), +DEFINE_KEYFIELD(m_bEnableShadows, FIELD_BOOLEAN, "enableshadows"), +DEFINE_KEYFIELD(m_bLightOnlyTarget, FIELD_BOOLEAN, "lightonlytarget"), +DEFINE_KEYFIELD(m_bLightWorld, FIELD_BOOLEAN, "lightworld"), +DEFINE_KEYFIELD(m_bCameraSpace, FIELD_BOOLEAN, "cameraspace"), +DEFINE_KEYFIELD(m_flAmbient, FIELD_FLOAT, "ambient"), +DEFINE_AUTO_ARRAY_KEYFIELD(m_SpotlightTextureName, FIELD_CHARACTER, "texturename"), +DEFINE_KEYFIELD(m_nSpotlightTextureFrame, FIELD_INTEGER, "textureframe"), +DEFINE_KEYFIELD(m_flNearZ, FIELD_FLOAT, "nearz"), +DEFINE_KEYFIELD(m_flFarZ, FIELD_FLOAT, "farz"), +DEFINE_KEYFIELD(m_nShadowQuality, FIELD_INTEGER, "shadowquality"), +DEFINE_FIELD(m_LinearFloatLightColor, FIELD_VECTOR), +DEFINE_THINKFUNC(InitialThink), +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST(CEnvCascadeLightSecond, DT_EnvCascadeLightSecond) +SendPropEHandle(SENDINFO(m_hTargetEntity)), +SendPropBool(SENDINFO(m_bState)), +SendPropFloat(SENDINFO(m_flLightFOV)), +SendPropBool(SENDINFO(m_bEnableShadows)), +SendPropBool(SENDINFO(m_bLightOnlyTarget)), +SendPropBool(SENDINFO(m_bLightWorld)), +SendPropBool(SENDINFO(m_bCameraSpace)), +SendPropVector(SENDINFO(m_LinearFloatLightColor)), +SendPropFloat(SENDINFO(m_flAmbient)), +SendPropString(SENDINFO(m_SpotlightTextureName)), +SendPropInt(SENDINFO(m_nSpotlightTextureFrame)), +SendPropFloat(SENDINFO(m_flNearZ), 16, SPROP_ROUNDDOWN, 0.0f, 500.0f), +SendPropFloat(SENDINFO(m_flFarZ), 18, SPROP_ROUNDDOWN, 0.0f, 1500.0f), +SendPropInt(SENDINFO(m_nShadowQuality), 1, SPROP_UNSIGNED) // Just one bit for now +END_SEND_TABLE() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CEnvCascadeLightSecond::CEnvCascadeLightSecond(void) +{ + m_bState = true; + m_flLightFOV = 45.0f; + m_bEnableShadows = true; + m_bLightOnlyTarget = false; + m_bLightWorld = true; + m_bCameraSpace = false; + + Q_strcpy(m_SpotlightTextureName.GetForModify(), "tools\\fakecsm\\mask_ring"); + m_nSpotlightTextureFrame = 0; + m_LinearFloatLightColor.Init(1.0f, 1.0f, 1.0f); + m_flAmbient = 0.0f; + m_flNearZ = 8000.0f; + m_flFarZ = 16000.0f; + m_nShadowQuality = 0; +} + +void UTIL_ColorStringToLinearFloatColorCSMFakeSecond(Vector& color, const char* pString) +{ + float tmp[4]; + UTIL_StringToFloatArray(tmp, 4, pString); + if (tmp[3] <= 0.0f) + { + tmp[3] = 255.0f; + } + tmp[3] *= (1.0f / 255.0f); + color.x = GammaToLinear(tmp[0] * (1.0f / 255.0f)) * tmp[3]; + color.y = GammaToLinear(tmp[1] * (1.0f / 255.0f)) * tmp[3]; + color.z = GammaToLinear(tmp[2] * (1.0f / 255.0f)) * tmp[3]; +} + +bool CEnvCascadeLightSecond::KeyValue(const char* szKeyName, const char* szValue) +{ + if (FStrEq(szKeyName, "lightcolor")) + { + Vector tmp; + UTIL_ColorStringToLinearFloatColorCSMFakeSecond(tmp, szValue); + m_LinearFloatLightColor = tmp; + } + else + { + return BaseClass::KeyValue(szKeyName, szValue); + } + + return true; +} + +void CEnvCascadeLightSecond::Activate(void) +{ + if (GetSpawnFlags() & ENV_CASCADE_STARTON) + { + m_bState = true; + } + + SetThink(&CEnvCascadeLightSecond::InitialThink); + SetNextThink(gpGlobals->curtime + 0.1f); + + BaseClass::Activate(); +} + +void CEnvCascadeLightSecond::InitialThink(void) +{ + float bibigon = defdist.GetFloat() / curdist.GetFloat(); + m_flLightFOV = csm_second_fov.GetFloat() * bibigon; + m_hTargetEntity = gEntList.FindEntityByName(NULL, m_target); +} + +int CEnvCascadeLightSecond::UpdateTransmitState() +{ + return SetTransmitState(FL_EDICT_ALWAYS); +} + + + +//----------------------------------------------------------------------------- +// Purpose: main csm code +//----------------------------------------------------------------------------- +class CEnvCascadeLight : public CPointEntity +{ + DECLARE_CLASS(CEnvCascadeLight, CPointEntity); +public: + DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); + + CEnvCascadeLight(); + bool KeyValue(const char* szKeyName, const char* szValue); + + // Always transmit to clients + virtual int UpdateTransmitState(); + virtual void Activate(void); + void Spawn(); + void Preparation(); + + void InputTurnOn(inputdata_t& inputdata); + void InputTurnOff(inputdata_t& inputdata); + void InputSetEnableShadows(inputdata_t& inputdata); + void InputSetLightColor( inputdata_t &inputdata ); + void InputSetSpotlightTexture(inputdata_t& inputdata); + void InputSetAmbient(inputdata_t& inputdata); + + void InitialThink(void); + + CNetworkHandle(CBaseEntity, m_hTargetEntity); + +private: + CNetworkVar(bool, m_bState); + CNetworkVar(float, m_flLightFOV); + CNetworkVar(bool, EnableAngleFromEnv); + CNetworkVar(bool, m_bEnableShadows); + CNetworkVar(bool, m_bLightOnlyTarget); + CNetworkVar(bool, m_bLightWorld); + CNetworkVar(bool, m_bCameraSpace); + CNetworkVector(m_LinearFloatLightColor); + CNetworkVar(float, m_flAmbient); + CNetworkString(m_SpotlightTextureName, MAX_PATH); + CNetworkVar(int, m_nSpotlightTextureFrame); + CNetworkVar(float, m_flNearZ); + CNetworkVar(float, m_flFarZ); + CNetworkVar(int, m_nShadowQuality); +}; + +LINK_ENTITY_TO_CLASS(env_cascade_light, CEnvCascadeLight); + +BEGIN_DATADESC(CEnvCascadeLight) +DEFINE_FIELD(m_hTargetEntity, FIELD_EHANDLE), +DEFINE_FIELD(m_bState, FIELD_BOOLEAN), +DEFINE_KEYFIELD(m_bEnableShadows, FIELD_BOOLEAN, "enableshadows"), +DEFINE_KEYFIELD(m_bLightOnlyTarget, FIELD_BOOLEAN, "lightonlytarget"), +DEFINE_KEYFIELD(m_bLightWorld, FIELD_BOOLEAN, "lightworld"), +DEFINE_KEYFIELD(m_bCameraSpace, FIELD_BOOLEAN, "cameraspace"), +DEFINE_KEYFIELD(m_flAmbient, FIELD_FLOAT, "ambient"), +DEFINE_AUTO_ARRAY_KEYFIELD(m_SpotlightTextureName, FIELD_CHARACTER, "texturename"), +DEFINE_KEYFIELD(m_nSpotlightTextureFrame, FIELD_INTEGER, "textureframe"), +DEFINE_KEYFIELD(m_flNearZ, FIELD_FLOAT, "nearz"), +DEFINE_KEYFIELD(m_flFarZ, FIELD_FLOAT, "farz"), +DEFINE_KEYFIELD(m_nShadowQuality, FIELD_INTEGER, "shadowquality"), +DEFINE_FIELD(m_LinearFloatLightColor, FIELD_VECTOR), +DEFINE_KEYFIELD(EnableAngleFromEnv, FIELD_BOOLEAN, "uselightenvangles"), + +DEFINE_INPUTFUNC(FIELD_VOID, "TurnOn", InputTurnOn), +DEFINE_INPUTFUNC(FIELD_VOID, "TurnOff", InputTurnOff), +DEFINE_INPUTFUNC(FIELD_BOOLEAN, "EnableShadows", InputSetEnableShadows), +// this is broken . . need to be able to set color and intensity like light_dynamic +// DEFINE_INPUTFUNC( FIELD_COLOR32, "LightColor", InputSetLightColor ), +DEFINE_INPUTFUNC(FIELD_FLOAT, "Ambient", InputSetAmbient), +DEFINE_INPUTFUNC(FIELD_STRING, "SpotlightTexture", InputSetSpotlightTexture), +DEFINE_THINKFUNC(InitialThink), +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST(CEnvCascadeLight, DT_EnvCascadeLight) +SendPropEHandle(SENDINFO(m_hTargetEntity)), +SendPropBool(SENDINFO(m_bState)), +SendPropFloat(SENDINFO(m_flLightFOV)), +SendPropBool(SENDINFO(m_bEnableShadows)), +SendPropBool(SENDINFO(m_bLightOnlyTarget)), +SendPropBool(SENDINFO(m_bLightWorld)), +SendPropBool(SENDINFO(m_bCameraSpace)), +SendPropVector(SENDINFO(m_LinearFloatLightColor)), +SendPropFloat(SENDINFO(m_flAmbient)), +SendPropString(SENDINFO(m_SpotlightTextureName)), +SendPropInt(SENDINFO(m_nSpotlightTextureFrame)), +SendPropFloat(SENDINFO(m_flNearZ), 16, SPROP_ROUNDDOWN, 0.0f, 500.0f), +SendPropFloat(SENDINFO(m_flFarZ), 18, SPROP_ROUNDDOWN, 0.0f, 1500.0f), +SendPropInt(SENDINFO(m_nShadowQuality), 1, SPROP_UNSIGNED) // Just one bit for now +END_SEND_TABLE() + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CEnvCascadeLight::CEnvCascadeLight(void) +{ + m_bState = true; + m_flLightFOV = 45.0f; + m_bEnableShadows = true; + m_bLightOnlyTarget = false; + m_bLightWorld = true; + m_bCameraSpace = false; + EnableAngleFromEnv = false; + + Q_strcpy(m_SpotlightTextureName.GetForModify(), "tools\\fakecsm\\mask_center"); + m_nSpotlightTextureFrame = 0; + m_LinearFloatLightColor.Init(1.0f, 1.0f, 1.0f); + m_flAmbient = 0.0f; + m_flNearZ = 8000.0f; + m_flFarZ = 16000.0f; + m_nShadowQuality = 0; +} + +void CEnvCascadeLight::Preparation() +{ + CreateEntityByName("csmorigin"); + CreateEntityByName("second_csm"); + defFOV.SetValue(m_flLightFOV); + CBaseEntity* CSMOrigin = NULL; + CBaseEntity* CSMSecond = NULL; + + CSMOrigin = gEntList.FindEntityByClassname(CSMOrigin, "csmorigin"); + //if origin is exist + if (CSMOrigin) + { + + CSMSecond = gEntList.FindEntityByClassname(CSMSecond, "second_csm"); + //if second csm is exist + if (CSMSecond) + { + CEnvCascadeLightSecond* SecondCSM = dynamic_cast(CSMSecond); + SecondCSM->SetAbsAngles(GetAbsAngles()); + SecondCSM->SetAbsOrigin(GetAbsOrigin()); + SecondCSM->SetParent(GetBaseEntity()); + SecondCSM->m_LinearFloatLightColor = m_LinearFloatLightColor; + + DispatchSpawn(SecondCSM); + } + + CLightOrigin* pEnv = dynamic_cast(CSMOrigin); + if (EnableAngleFromEnv) + { + pEnv->angFEnv = true; + } + else + { + pEnv->SetAbsAngles(GetAbsAngles()); + } + SetParent(pEnv, 1); + SetAbsOrigin(Vector(pEnv->GetAbsOrigin().x, pEnv->GetAbsOrigin().y, pEnv->GetAbsOrigin().z + curdist.GetInt())); + + float bibigon = defdist.GetFloat() / curdist.GetFloat(); + curFOV.SetValue(defFOV.GetFloat() * bibigon); + m_flLightFOV = curFOV.GetFloat(); + DispatchSpawn(CSMOrigin); + } + else + { + Msg("Main csm entity can't find \"csmorigin\" entity!"); + } + +} + +void CEnvCascadeLight::Spawn() +{ + Preparation(); +} + +void UTIL_ColorStringToLinearFloatColorCSMFake(Vector& color, const char* pString) +{ + float tmp[4]; + UTIL_StringToFloatArray(tmp, 4, pString); + if (tmp[3] <= 0.0f) + { + tmp[3] = 255.0f; + } + tmp[3] *= (1.0f / 255.0f); + color.x = GammaToLinear(tmp[0] * (1.0f / 255.0f)) * tmp[3]; + color.y = GammaToLinear(tmp[1] * (1.0f / 255.0f)) * tmp[3]; + color.z = GammaToLinear(tmp[2] * (1.0f / 255.0f)) * tmp[3]; +} + +bool CEnvCascadeLight::KeyValue(const char* szKeyName, const char* szValue) +{ + if (FStrEq(szKeyName, "lightcolor")) + { + Vector tmp; + UTIL_ColorStringToLinearFloatColorCSMFake(tmp, szValue); + m_LinearFloatLightColor = tmp; + } + else + { + return BaseClass::KeyValue(szKeyName, szValue); + } + + return true; +} + +void CEnvCascadeLight::InputTurnOn(inputdata_t& inputdata) +{ + m_bState = true; +} + +void CEnvCascadeLight::InputTurnOff(inputdata_t& inputdata) +{ + m_bState = false; +} + + +void CEnvCascadeLight::InputSetEnableShadows(inputdata_t& inputdata) +{ + m_bEnableShadows = inputdata.value.Bool(); +} + +//void CEnvProjectedTexture::InputSetLightColor( inputdata_t &inputdata ) +//{ + //m_cLightColor = inputdata.value.Color32(); +//} + +void CEnvCascadeLight::InputSetAmbient(inputdata_t& inputdata) +{ + m_flAmbient = inputdata.value.Float(); +} + +void CEnvCascadeLight::InputSetSpotlightTexture(inputdata_t& inputdata) +{ + Q_strcpy(m_SpotlightTextureName.GetForModify(), inputdata.value.String()); +} + +void CEnvCascadeLight::Activate(void) +{ + if (GetSpawnFlags() & ENV_CASCADE_STARTON) + { + m_bState = true; + } + + SetThink(&CEnvCascadeLight::InitialThink); + SetNextThink(gpGlobals->curtime + 0.1f); + + BaseClass::Activate(); +} + +void CEnvCascadeLight::InitialThink(void) +{ + m_hTargetEntity = gEntList.FindEntityByName(NULL, m_target); +} + +int CEnvCascadeLight::UpdateTransmitState() +{ + return SetTransmitState(FL_EDICT_ALWAYS); +} diff --git a/server/lights.h b/server/lights.h new file mode 100644 index 0000000..b457da9 --- /dev/null +++ b/server/lights.h @@ -0,0 +1,57 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#ifndef LIGHTS_H +#define LIGHTS_H +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CLight : public CPointEntity +{ +public: + DECLARE_CLASS( CLight, CPointEntity ); + + bool KeyValue( const char *szKeyName, const char *szValue ); + void Spawn( void ); + void FadeThink( void ); + void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); + + void TurnOn( void ); + void TurnOff( void ); + void Toggle( void ); + + // Input handlers + void InputSetPattern( inputdata_t &inputdata ); + void InputFadeToPattern( inputdata_t &inputdata ); + + void InputToggle( inputdata_t &inputdata ); + void InputTurnOn( inputdata_t &inputdata ); + void InputTurnOff( inputdata_t &inputdata ); + + DECLARE_DATADESC(); + +private: + int m_iStyle; + int m_iDefaultStyle; + string_t m_iszPattern; + char m_iCurrentFade; + char m_iTargetFade; +}; + +class CEnvLight : public CLight +{ +public: + DECLARE_CLASS(CEnvLight, CLight); + + bool KeyValue(const char* szKeyName, const char* szValue); + void Spawn(void); +}; + +#endif // LIGHTS_H