Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

366 lines
8.6 KiB

  1. //========= Copyright � 1996-2010, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: global dynamic light with cascaded shadow mapping
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "lights.h"
  9. #include "env_cascade_light.h"
  10. // memdbgon must be the last include file in a .cpp file!!!
  11. #include "tier0/memdbgon.h"
  12. //#define CsmDbgMsg Msg
  13. #define CsmDbgMsg(x)
  14. ConVar cl_csm_auto_entity( "cl_csm_auto_entity", "1", 0, "" );
  15. CCascadeLight *g_pCascadeLight;
  16. LINK_ENTITY_TO_CLASS(env_cascade_light, CCascadeLight);
  17. BEGIN_DATADESC( CCascadeLight )
  18. DEFINE_KEYFIELD( m_bEnabled, FIELD_BOOLEAN, "enabled" ),
  19. DEFINE_KEYFIELD( m_bStartDisabled, FIELD_BOOLEAN, "StartDisabled" ),
  20. DEFINE_FIELD( m_LightColor, FIELD_COLOR32 ),
  21. DEFINE_FIELD( m_LightColorScale, FIELD_INTEGER ),
  22. // Inputs
  23. DEFINE_INPUTFUNC( FIELD_COLOR32, "LightColor", InputSetLightColor ),
  24. DEFINE_INPUTFUNC( FIELD_INTEGER, "LightColorScale", InputSetLightColorScale ),
  25. DEFINE_INPUTFUNC( FIELD_STRING, "SetAngles", InputSetAngles ),
  26. DEFINE_INPUTFUNC( FIELD_VOID, "Enable", InputEnable ),
  27. DEFINE_INPUTFUNC( FIELD_VOID, "Disable", InputDisable ),
  28. END_DATADESC()
  29. IMPLEMENT_SERVERCLASS_ST_NOBASE(CCascadeLight, DT_CascadeLight)
  30. SendPropVector(SENDINFO(m_shadowDirection), -1, SPROP_NOSCALE ),
  31. SendPropVector(SENDINFO(m_envLightShadowDirection), -1, SPROP_NOSCALE ),
  32. SendPropBool(SENDINFO(m_bEnabled) ),
  33. SendPropBool(SENDINFO(m_bUseLightEnvAngles) ),
  34. SendPropInt(SENDINFO(m_LightColor), 32, SPROP_UNSIGNED, SendProxy_Color32ToInt32 ),
  35. SendPropInt(SENDINFO(m_LightColorScale), 32, 0, SendProxy_Int32ToInt32 ),
  36. SendPropFloat(SENDINFO(m_flMaxShadowDist), 0, SPROP_NOSCALE ),
  37. END_SEND_TABLE()
  38. float CCascadeLight::m_flEnvLightShadowPitch;
  39. QAngle CCascadeLight::m_EnvLightShadowAngles;
  40. bool CCascadeLight::m_bEnvLightShadowValid;
  41. color32 CCascadeLight::m_EnvLightColor;
  42. int CCascadeLight::m_EnvLightColorScale;
  43. CCascadeLight::CCascadeLight() :
  44. CBaseEntity()
  45. {
  46. CsmDbgMsg( "CCascadeLight::CCascadeLight\n" );
  47. m_bEnabled = true;
  48. color32 tmp = { 255, 255, 255, 1 };
  49. m_LightColor = tmp;
  50. m_LightColorScale = 255;
  51. QAngle angles;
  52. angles.Init( 50, 43, 0 );
  53. Vector vForward;
  54. AngleVectors( angles, &vForward );
  55. m_shadowDirection = vForward;
  56. //m_shadowDirection.Init( 0.0f, 0.0f, -1.0f );
  57. m_envLightShadowDirection = m_shadowDirection;
  58. m_bUseLightEnvAngles = true;
  59. m_flMaxShadowDist = 400.0f;
  60. g_pCascadeLight = this;
  61. }
  62. CCascadeLight::~CCascadeLight()
  63. {
  64. g_pCascadeLight = NULL;
  65. CsmDbgMsg( "CCascadeLight::~CCascadeLight\n" );
  66. }
  67. //------------------------------------------------------------------------------
  68. // Purpose : Send even though we don't have a model
  69. //------------------------------------------------------------------------------
  70. int CCascadeLight::UpdateTransmitState()
  71. {
  72. // ALWAYS transmit to all clients.
  73. return SetTransmitState( FL_EDICT_ALWAYS );
  74. }
  75. bool CCascadeLight::KeyValue( const char *szKeyName, const char *szValue )
  76. {
  77. if ( FStrEq( szKeyName, "color" ) )
  78. {
  79. /* unused?
  80. float tmp[4];
  81. UTIL_StringToFloatArray( tmp, 4, szValue );
  82. m_LightColor.SetR( tmp[0] );
  83. m_LightColor.SetG( tmp[1] );
  84. m_LightColor.SetB( tmp[2] );
  85. m_LightColor.SetA( tmp[3] );*/
  86. }
  87. else if ( FStrEq( szKeyName, "angles" ) )
  88. {
  89. QAngle angles;
  90. UTIL_StringToVector( angles.Base(), szValue );
  91. if (angles == vec3_angle)
  92. {
  93. angles.Init( 50, 43, 0 );
  94. }
  95. Vector vForward;
  96. AngleVectors( angles, &vForward );
  97. m_shadowDirection = vForward;
  98. return true;
  99. }
  100. else if ( FStrEq( szKeyName, "uselightenvangles" ) )
  101. {
  102. m_bUseLightEnvAngles = ( atoi( szValue ) != 0 );
  103. return true;
  104. }
  105. else if ( FStrEq( szKeyName, "maxshadowdistance" ) )
  106. {
  107. m_flMaxShadowDist = atof( szValue );
  108. return true;
  109. }
  110. return BaseClass::KeyValue( szKeyName, szValue );
  111. }
  112. bool CCascadeLight::GetKeyValue( const char *szKeyName, char *szValue, int iMaxLen )
  113. {
  114. if ( FStrEq( szKeyName, "color" ) )
  115. {
  116. // path unused?
  117. Q_snprintf( szValue, iMaxLen, "%d %d %d %d", m_LightColor.GetR(), m_LightColor.GetG(), m_LightColor.GetB(), m_LightColor.GetA() );
  118. return true;
  119. }
  120. return BaseClass::GetKeyValue( szKeyName, szValue, iMaxLen );
  121. }
  122. //------------------------------------------------------------------------------
  123. // Purpose :
  124. //------------------------------------------------------------------------------
  125. void CCascadeLight::Spawn( void )
  126. {
  127. Precache();
  128. SetSolid( SOLID_NONE );
  129. if( m_bStartDisabled )
  130. {
  131. m_bEnabled = false;
  132. }
  133. else
  134. {
  135. m_bEnabled = true;
  136. }
  137. if ( m_bEnvLightShadowValid )
  138. {
  139. UpdateEnvLight();
  140. }
  141. //SetClassname( "cascadelight" );
  142. BaseClass::Spawn();
  143. }
  144. void CCascadeLight::Release( void )
  145. {
  146. g_pCascadeLight = NULL;
  147. }
  148. //------------------------------------------------------------------------------
  149. // Purpose :
  150. //------------------------------------------------------------------------------
  151. void CCascadeLight::OnActivate()
  152. {
  153. }
  154. //------------------------------------------------------------------------------
  155. // Purpose :
  156. //------------------------------------------------------------------------------
  157. void CCascadeLight::OnDeactivate()
  158. {
  159. }
  160. //------------------------------------------------------------------------------
  161. // Input values
  162. //------------------------------------------------------------------------------
  163. void CCascadeLight::InputSetAngles( inputdata_t &inputdata )
  164. {
  165. const char *pAngles = inputdata.value.String();
  166. QAngle angles;
  167. UTIL_StringToVector( angles.Base(), pAngles );
  168. Vector vTemp;
  169. AngleVectors( angles, &vTemp );
  170. m_shadowDirection = vTemp;
  171. }
  172. //------------------------------------------------------------------------------
  173. // Purpose : Input handlers
  174. //------------------------------------------------------------------------------
  175. void CCascadeLight::InputEnable( inputdata_t &inputdata )
  176. {
  177. m_bEnabled = true;
  178. if ( g_pCascadeLight )
  179. {
  180. g_pCascadeLight->UpdateEnvLight();
  181. }
  182. }
  183. void CCascadeLight::InputDisable( inputdata_t &inputdata )
  184. {
  185. m_bEnabled = false;
  186. if ( g_pCascadeLight )
  187. {
  188. g_pCascadeLight->UpdateEnvLight();
  189. }
  190. }
  191. void CCascadeLight::InputSetLightColor( inputdata_t &inputdata )
  192. {
  193. m_LightColor = inputdata.value.Color32();
  194. }
  195. void CCascadeLight::InputSetLightColorScale( inputdata_t &inputdata )
  196. {
  197. m_LightColorScale = inputdata.value.Int();
  198. if ( g_pCascadeLight )
  199. {
  200. g_pCascadeLight->UpdateEnvLight();
  201. }
  202. }
  203. void CCascadeLight::SetLightColor( int r, int g, int b, int a )
  204. {
  205. m_EnvLightColor.r = r;
  206. m_EnvLightColor.g = g;
  207. m_EnvLightColor.b = b;
  208. m_EnvLightColor.a = 0; // use light scale as potentially > 255
  209. m_EnvLightColorScale = a;
  210. if ( g_pCascadeLight )
  211. {
  212. g_pCascadeLight->UpdateEnvLight();
  213. }
  214. }
  215. void CCascadeLight::SetEnabled( bool bEnable )
  216. {
  217. m_bEnabled = bEnable;
  218. }
  219. void CCascadeLight::UpdateEnvLight()
  220. {
  221. QAngle angles;
  222. angles.x = -m_flEnvLightShadowPitch;
  223. angles.y = m_EnvLightShadowAngles.y;
  224. angles.z = 0;
  225. Vector vForward;
  226. AngleVectors( angles, &vForward );
  227. m_envLightShadowDirection = vForward;
  228. m_LightColor = m_EnvLightColor;
  229. m_LightColorScale = m_EnvLightColorScale;
  230. }
  231. void CCascadeLight::SetEnvLightShadowPitch( float flPitch )
  232. {
  233. m_flEnvLightShadowPitch = flPitch;
  234. m_bEnvLightShadowValid = true;
  235. if ( g_pCascadeLight )
  236. {
  237. g_pCascadeLight->UpdateEnvLight();
  238. }
  239. }
  240. void CCascadeLight::SetEnvLightShadowAngles( const QAngle &angles )
  241. {
  242. m_EnvLightShadowAngles = angles;
  243. m_bEnvLightShadowValid = true;
  244. if ( g_pCascadeLight )
  245. {
  246. g_pCascadeLight->UpdateEnvLight();
  247. }
  248. }
  249. class CCSMLightManager : public CAutoGameSystemPerFrame
  250. {
  251. public:
  252. CCSMLightManager()
  253. {
  254. }
  255. virtual ~CCSMLightManager()
  256. {
  257. }
  258. virtual void LevelInitPreEntity()
  259. {
  260. CsmDbgMsg( "**** LevelInitPreEntity\n" );
  261. }
  262. virtual void LevelInitPostEntity()
  263. {
  264. CsmDbgMsg( "**** LevelInitPostEntity\n" );
  265. if ( !cl_csm_auto_entity.GetBool() )
  266. return;
  267. if ( g_pCascadeLight )
  268. return;
  269. // Create the env_cascade_light automatically for cs:go - this is a hack that will hopefully go away as we add the entity to all of our maps.
  270. CBaseEntity *entity = dynamic_cast< CBaseEntity * >( CreateEntityByName( "env_cascade_light" ) );
  271. if (entity)
  272. {
  273. entity->Precache();
  274. entity->KeyValue( "targetname", "cascadelight" );
  275. DispatchSpawn(entity);
  276. }
  277. }
  278. virtual void LevelShutdownPreEntity()
  279. {
  280. CsmDbgMsg( "**** LevelShutdownPreEntity\n" );
  281. }
  282. virtual void LevelShutdownPostEntity()
  283. {
  284. CsmDbgMsg( "**** LevelShutdownPostEntity\n" );
  285. }
  286. virtual void Shutdown()
  287. {
  288. CsmDbgMsg( "**** Shutdown\n" );
  289. }
  290. };
  291. CCSMLightManager g_CSMLightManager;
  292. void C_CSM_Server_Status( const CCommand& args )
  293. {
  294. Msg( "Entity exists: %u\n", g_pCascadeLight != NULL );
  295. }
  296. static ConCommand cl_csm_server_status("cl_csm_server_status", C_CSM_Server_Status, "Usage:\n cl_csm_server_status\n", 0);