diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /mp/src/game/client/c_dynamiclight.cpp | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/game/client/c_dynamiclight.cpp')
| -rw-r--r-- | mp/src/game/client/c_dynamiclight.cpp | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/mp/src/game/client/c_dynamiclight.cpp b/mp/src/game/client/c_dynamiclight.cpp new file mode 100644 index 00000000..b177b4da --- /dev/null +++ b/mp/src/game/client/c_dynamiclight.cpp @@ -0,0 +1,237 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Dynamic light
+//
+// $Workfile: $
+// $Date: $
+// $NoKeywords: $
+//=============================================================================//
+#include "cbase.h"
+#include "dlight.h"
+#include "iefx.h"
+#include "iviewrender.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+#if HL2_EPISODIC
+// In Episodic we unify the NO_WORLD_ILLUMINATION lights to use
+// the more efficient elight structure instead. This should theoretically
+// be extended to other projects but may have unintended consequences
+// and bears more thorough testing.
+//
+// For an earlier iteration on this technique see changelist 214433,
+// which had a specific flag for use of elights.
+#define DLIGHT_NO_WORLD_USES_ELIGHT 1
+#endif
+
+
+//-----------------------------------------------------------------------------
+// A dynamic light, with the goofy hack needed for spotlights
+//-----------------------------------------------------------------------------
+class C_DynamicLight : public C_BaseEntity
+{
+public:
+ DECLARE_CLASS( C_DynamicLight, C_BaseEntity );
+ DECLARE_CLIENTCLASS();
+
+ C_DynamicLight();
+
+public:
+ void OnDataChanged(DataUpdateType_t updateType);
+ bool ShouldDraw();
+ void ClientThink( void );
+ void Release( void );
+
+ unsigned char m_Flags;
+ unsigned char m_LightStyle;
+
+ float m_Radius;
+ int m_Exponent;
+ float m_InnerAngle;
+ float m_OuterAngle;
+ float m_SpotRadius;
+
+private:
+ dlight_t* m_pDynamicLight;
+ dlight_t* m_pSpotlightEnd;
+
+
+ inline bool ShouldBeElight() { return (m_Flags & DLIGHT_NO_WORLD_ILLUMINATION); }
+};
+
+IMPLEMENT_CLIENTCLASS_DT(C_DynamicLight, DT_DynamicLight, CDynamicLight)
+ RecvPropInt (RECVINFO(m_Flags)),
+ RecvPropInt (RECVINFO(m_LightStyle)),
+ RecvPropFloat (RECVINFO(m_Radius)),
+ RecvPropInt (RECVINFO(m_Exponent)),
+ RecvPropFloat (RECVINFO(m_InnerAngle)),
+ RecvPropFloat (RECVINFO(m_OuterAngle)),
+ RecvPropFloat (RECVINFO(m_SpotRadius)),
+END_RECV_TABLE()
+
+
+//------------------------------------------------------------------------------
+// Purpose :
+//------------------------------------------------------------------------------
+C_DynamicLight::C_DynamicLight(void) : m_pSpotlightEnd(0), m_pDynamicLight(0)
+{
+}
+
+
+//------------------------------------------------------------------------------
+// Purpose :
+//------------------------------------------------------------------------------
+void C_DynamicLight::OnDataChanged(DataUpdateType_t updateType)
+{
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ SetNextClientThink(gpGlobals->curtime + 0.05);
+ }
+
+ BaseClass::OnDataChanged( updateType );
+}
+
+
+//------------------------------------------------------------------------------
+// Purpose :
+//------------------------------------------------------------------------------
+bool C_DynamicLight::ShouldDraw()
+{
+ return false;
+}
+
+//------------------------------------------------------------------------------
+// Purpose : Disable drawing of this light when entity perishes
+//------------------------------------------------------------------------------
+void C_DynamicLight::Release()
+{
+ if (m_pDynamicLight)
+ {
+ m_pDynamicLight->die = gpGlobals->curtime;
+ m_pDynamicLight = 0;
+ }
+
+ if (m_pSpotlightEnd)
+ {
+ m_pSpotlightEnd->die = gpGlobals->curtime;
+ m_pSpotlightEnd = 0;
+ }
+
+ BaseClass::Release();
+}
+
+
+//------------------------------------------------------------------------------
+// Purpose :
+//------------------------------------------------------------------------------
+void C_DynamicLight::ClientThink(void)
+{
+ Vector forward;
+ AngleVectors( GetAbsAngles(), &forward );
+
+ if ( (m_Flags & DLIGHT_NO_MODEL_ILLUMINATION) == 0 )
+ {
+ // Deal with the model light
+ if ( !m_pDynamicLight || (m_pDynamicLight->key != index) )
+ {
+#if DLIGHT_NO_WORLD_USES_ELIGHT
+ m_pDynamicLight = ShouldBeElight() != 0
+ ? effects->CL_AllocElight( index )
+ : effects->CL_AllocDlight( index );
+#else
+ m_pDynamicLight = effects->CL_AllocDlight( index );
+#endif
+ Assert (m_pDynamicLight);
+ m_pDynamicLight->minlight = 0;
+ }
+
+ m_pDynamicLight->style = m_LightStyle;
+ m_pDynamicLight->radius = m_Radius;
+ m_pDynamicLight->flags = m_Flags;
+ if ( m_OuterAngle > 0 )
+ m_pDynamicLight->flags |= DLIGHT_NO_WORLD_ILLUMINATION;
+ m_pDynamicLight->color.r = m_clrRender->r;
+ m_pDynamicLight->color.g = m_clrRender->g;
+ m_pDynamicLight->color.b = m_clrRender->b;
+ m_pDynamicLight->color.exponent = m_Exponent; // this makes it match the world
+ m_pDynamicLight->origin = GetAbsOrigin();
+ m_pDynamicLight->m_InnerAngle = m_InnerAngle;
+ m_pDynamicLight->m_OuterAngle = m_OuterAngle;
+ m_pDynamicLight->die = gpGlobals->curtime + 1e6;
+ m_pDynamicLight->m_Direction = forward;
+ }
+ else
+ {
+ // In this case, the m_Flags could have changed; which is how we turn the light off
+ if (m_pDynamicLight)
+ {
+ m_pDynamicLight->die = gpGlobals->curtime;
+ m_pDynamicLight = 0;
+ }
+ }
+
+#if DLIGHT_NO_WORLD_USES_ELIGHT
+ if (( m_OuterAngle > 0 ) && !ShouldBeElight())
+#else
+ if (( m_OuterAngle > 0 ) && ((m_Flags & DLIGHT_NO_WORLD_ILLUMINATION) == 0))
+#endif
+ {
+ // Raycast to where the endpoint goes
+ // Deal with the environment light
+ if ( !m_pSpotlightEnd || (m_pSpotlightEnd->key != -index) )
+ {
+ m_pSpotlightEnd = effects->CL_AllocDlight( -index );
+ Assert (m_pSpotlightEnd);
+ }
+
+ // Trace a line outward, don't use hitboxes (too slow)
+ Vector end;
+ VectorMA( GetAbsOrigin(), m_Radius, forward, end );
+
+ trace_t pm;
+ C_BaseEntity::PushEnableAbsRecomputations( false ); // HACK don't recompute positions while doing RayTrace
+ UTIL_TraceLine( GetAbsOrigin(), end, MASK_NPCWORLDSTATIC, NULL, COLLISION_GROUP_NONE, &pm );
+ C_BaseEntity::PopEnableAbsRecomputations();
+ VectorCopy( pm.endpos, m_pSpotlightEnd->origin );
+
+ if (pm.fraction == 1.0f)
+ {
+ m_pSpotlightEnd->die = gpGlobals->curtime;
+ m_pSpotlightEnd = 0;
+ }
+ else
+ {
+ float falloff = 1.0 - pm.fraction;
+ falloff *= falloff;
+
+ m_pSpotlightEnd->style = m_LightStyle;
+ m_pSpotlightEnd->flags = DLIGHT_NO_MODEL_ILLUMINATION | (m_Flags & DLIGHT_DISPLACEMENT_MASK);
+ m_pSpotlightEnd->radius = m_SpotRadius; // * falloff;
+ m_pSpotlightEnd->die = gpGlobals->curtime + 1e6;
+ m_pSpotlightEnd->color.r = m_clrRender->r * falloff;
+ m_pSpotlightEnd->color.g = m_clrRender->g * falloff;
+ m_pSpotlightEnd->color.b = m_clrRender->b * falloff;
+ m_pSpotlightEnd->color.exponent = m_Exponent;
+
+ // For bumped lighting
+ m_pSpotlightEnd->m_Direction = forward;
+
+ // Update list of surfaces we influence
+ render->TouchLight( m_pSpotlightEnd );
+ }
+ }
+ else
+ {
+ // In this case, the m_Flags could have changed; which is how we turn the light off
+ if (m_pSpotlightEnd)
+ {
+ m_pSpotlightEnd->die = gpGlobals->curtime;
+ m_pSpotlightEnd = 0;
+ }
+ }
+
+ SetNextClientThink(gpGlobals->curtime + 0.001);
+}
+
|